数据存储资源是系统中最重要的组成部分,数据即一切,尤其分布式领域,主要关注以下几点:
MySQL是OLTP关系型数据库,支持ACID事务,是最主要的存储系统,目前使用的版本是5.7。
MySQL本身不是分布式系统,其支持的数据复制技术,本质上是为了数据容灾使用,但目前基于主从复制进行读写分离,减少单机的读压力。
MySQL服务如果托管在阿里云,可以使用高可用版本,秒级的主从切换,基于云盘的磁盘扩容技术,能够快速复制一个只读节点,减少了很多自建MySQL遇到的各种问题,另外其还提供了很多额外的功能,比如索引分析、SQL审查、慢查询分析、动态扩容。
虽然云托管RDS,但本质上还是MySQL,仍然会遇到很多问题,比如:
云托管的RDS本质上还是基于ECS+云盘搭建的,数据的增长、备份、性能、迁移、升级、只读实例、磁盘容量、Binlog延迟还是会显露出来。
那未来如何?其实云厂商也在探索,提出了云原生数据库、云原生分布式数据的概念,比如阿里云的PolarDB、PolarDB-X。
云原生数据库关注成本、性能、在线业务扩展、数据安全,它的核心技术包括计算和存储分离,物理复制Binlog行复制模式,共享存储设备,存储之间通过RDMA高速网络协议传输,同时PolarDB-X支持分区模式,解决了分库分表的问题。
经过这些创新,传统MySQL的弊端被解决了,比如同步延迟、备份、成本、分库分表、性能。
未来,可以将核心数据库迁移至云原生数据库,保障核心业务的稳定性和扩展性,而对于非OLTP业务可以选择其他数据库,且制定MySQL应用规范,明确哪些业务模式使用MySQL,索引正确设计、容量规划、SQL语句使用规范等等。
Redis是K/V数据库,它基于单线程、内存操作,所以性能非常高。另外支持丰富的数据结构,比如字符串、Hash、List、集合,应用场景非常广泛。
它通过AOF和RDB保障数据持久化,通过复制技术进行数据备份,也支持通过哨兵和分区提供高可用性和容量伸缩,通过LUA脚本支持多条命令的事务操作。
Redis虽然是一个单机系统,但通过复制、集群技术也可以认为是一个分布式存储系统,目前西五街在大量使用,主要分为三类应用:
阿里云云托管Redis社区版5.0服务集群版。
在应用设计上存在以下几个问题:
通过阿里云Redis提供的部署架构,可以很好的理解它的应用场景:
后续确定Redis使用规范,拆分存储和缓存场景,基于统一Lib包,就能解决大部分问题。
Elasticseach是一个近实时的分布式搜索引擎和分析引擎。
作为一个搜索引擎,目前在开源领域已经是排名第一的数据库了;基于倒排索引,具有很强的检索能力,所以不管是应用还是在大数据领域,它都是一个非常通用的分析引擎。
近实时表示Elasticseach应用场景必须要有所了解,它不支持ACID,所以无法是一个OLTP数据库,但使用压力小了很多,在做策略分析、后台应用、即时查询上有很广泛的场景。
作为一个分布式应用,通过副本集机制解决高可用的问题,能够解决单机故障的问题,但如果数据被误删除,还是需要有备份机制,比如Elasticseach的快照机制。
副本集的同步最终达到一致性,为了写入性能,也可以配置主节点写入完成即返回给客户端。
在容量可扩展方面,可以采用分片机制解决容量横向伸缩的问题,将数据分到不同节点的不同分片上,如果要调整分片,需要reindex。
在性能方面,通过多副本集节点分担查询压力。也可以使用专门的Transport节点分担date Node节点的压力,将分片查询,副本查询等路由和合并动作的结果汇总起来。
Elasticseach是ELK解决方案的一部分,其还包括很多服务,包括Filebat,Kibana,Logstash,在大数据领域也是很好的一个方向。
Elasticseach是在ELK上搭建的三节点服务,由于规模问题,目前也很少使用分片技术。核心是文章大宽表,用户大宽表。
结合了搜索场景和分析场景,通过Binlog+Canal+Kafka+Go服务将MySQL多个表汇总到一个大宽表,主要是文章信息的大宽表,一方面是满足搜索场景,另外满足策略和应用场景。
现在大宽表的应用模式非常多,基于Free Schema模式,查询模式非常灵活,通过订阅方式同步数据,也减轻了应用层的负担,数据正确性有很大的保障。
未来,对于Elasticseach的应用,一方面要加强性能调优,比如分片数据的不均匀,查询性能的优化,同时要提升可维护性,比如挖掘reindex、alias等功能,充分理解Elasticseach。
而在国内的云厂商中,都没有对Elasticseach做太大的升级,基本上就是将Elasticseach服务托管到云中。
Kakfa是一个分布式的高吞吐消息队列,订阅/消费模式追求的是高性能,而非存储容量。但其日志本身具有重放功能,也可以理解为一个分布式存储系统。
Kafka的核心功能包括:解耦、消峰、缓存,应用场景极为广泛,是系统不可缺少的一个组件。
作为分布式系统,它也有副本和分区机制,从而保障高可用和高吞吐。通过segment顺序写,保障了写性能非常高,而基于消费组组的概念,消费者吞吐能力也能横向扩展。同时每个broker都能负责查询,提升了吞吐能力
Kafka基于Zookeeper做很多分布式管理功能,包括Leader选举,负载均衡,Meta存储。
目前Kafka三节点集群是通过ECS自行搭建的,运行近一年,服务相对稳定,可维护性也较好,没有太多的管理工作,很多核心服务都已经使用了Kafka队列,后续原有基于Redis的队列也可以尽快迁移。
MongoDB是一个分布式的文档数据库,其目标是一个支持ACID事务的分布式数据库,因为是面向文档,所以模式非常灵活,结构松散,使用场景很规范,相比MySQL,其二进制的存储模式,压缩比非常高,存储成本会大幅减少,同时基于WiredTiger引擎,能够创建各种类型的索引,甚至子文档也能创建索引,从而提升查询性能
MongoDB通过oplog技术支持副本集,也支持分区,分区键可以自定义,因为有了分区,所以额外有了mongos路由服务器,config服务器,mongos路由服务器通过查询config服务器,向节点和分区发送服务。
MongoDB将一致性和性能诉求交给了客户端,通过read concern、write concern、read perference技术提供多种灵活性,比如你要求强一致性,那么就采用majority,你要求数据永远不丢失就配置journal为真。
MongoDB 4.0和MongoDB 4.2支持多文档的事务,分别支持复制集、分区维度的事务性,但使用和理解非常复杂,可能是分布式系统中最难学习的部分。
这样说明,不用刻意使用事务,对MongoDB进行良好的建模,做OLTP关系数据的补充,其在性能、成本、高可用、伸缩性方面是有优势的。其实在MySQL中,目前我们也很少使用跨表,跨语句的事务,所以不要太迷信事务,选择好应用场景。
除了查询,MongoDB也支持各种聚合操作,在分析领域也很有广泛的使用场景,这一点和Elasticseach很类似。
目前MongoDB三节点集群是通过ECS自行搭建的,存储规模较小,使用场景较少。
对比MySQL和Elasticseach,MongoDB还是有很广泛的应用场景,比如分析场景,对事务要求不高的场景,数据增长比较大的场景(比如私信数据),业务模式比较灵活的场景(比如各种条件的查询,聚合操作)。
不过和Elasticseach一样,各大云厂商一样,只是将这个服务托管到云,并没有做太多的优化。