写点什么

四款面向高并发、海量级分布式存储的分布式架构对比

用户头像
读字节
关注
发布于: 2021 年 03 月 14 日
四款面向高并发、海量级分布式存储的分布式架构对比

一、Redis 的分布式结构解读

首先 redis 采用去中心化的设计这个理解是不到位的。redis 分布式的模式,具有主从和集群两种,redis 社区的集群方案 redis cluster 采用的是去中心化设计。我们先看看 redis 的演化过程:



上图是标准的 Redis 主从模式,只有 Master 接收写入请求,并将写入的数据复制给一个或多个 Slave,这就形成了良好的读写分离机制,多个 Slave 就可以分担读操作。所以 redis 主从是标准的分布式中心化思想。

由于 redis 的应用场景大多是极高并发的内存 I/O,因此上图的主从模式下 Master 既要承担写入,又要承担对内各个节点复制,Master 的资源消耗很大,而且随着 slave 节点越多,这个问题越明显,因此,redis 又形成主从的一个变种形式:



上图是 redis 主从拓扑结构的一种树形结构,这个拓扑结构的好处在于 Master 不需要给无数多的 slave 节点进行复制数据了,交给处于下一层节点的 Slave 来处理。这样就能将 Master 的工作消耗尽量从复制中抽身。

可问题是像这种高并发的业务场景,Master 始终是一个隐患,因为它承受着所有的写操作,一旦崩溃,若没有 HA 解决方案,集群整体就不可用了。因此 redis 社区推出的集群方案,其实就是解决主的压力,很自然地就考虑到使用集群的分布式无中心模式。



上图中,左边是集群的中心模式,右边就是 redis cluster 使用的无中心模式。

redis cluster 一些细节:redis 无中心采用虚拟槽概念,这是独立于物理节点的,往往很容易将这块混淆,虚拟槽有 0~16383 个,redis 的数据进行 key 的 hash 计算(具体公式网上很多),确定这笔数据是进入哪个槽位,而物理节点负责哪些虚拟槽,这是由我们指定的。

例如:当 1 个 G 的数据按照一条条带有 key 的记录写入 redis cluster 的时候,那么集群的各个节点只要接受到数据,就计算此条记录应该归哪个槽哪个节点,归本节点就写入与槽位映射的数据,不归自己的,就反馈客户端真正需要写入的节点,客户端再向记录所属节点发起二次请求,这就完成了 1 个 G 的数据在集群中的分片。

我们先不论 redis cluster 更多的优劣问题,单从上面的演化可以看到 redis 的主从结构向 cluster 演化的过程,其实就是去中心的过程,就是为了让多客户端多业务请求并发性能可以得到更好负载。另外为了高可靠 HA,每个节点也可以在演变成 master/slave 的主从模式部署,即便是主节点宕掉,salve 也会顶替上来。HA 的缺点是节点数量又增加了一倍。

redis 与 rocketmq 最大的不同,redis 更偏重在线联机业务的高并发处理,而后者是海量积压数据流的大吞吐接收和消费。因此其选择分布式架构的目的也不同。当然这不代表着一定是中心化就不适合高并发,例如 LSM-Tree 代表的 oceanbase 作为集中式处理的特点,就很好的做到了在线联机业务的高并发写入,以及高速的热点数据(最近时间)查找。

另外,因为 redis cluster 作为分布式中每个节点都是对等的,那么就一定会存在集群管理上的一致性风险,由于在生产环境中各种异常情况都很特别,就会导致不同节点对集群的认可状态不一致,所以这时候手动介入调整每个节点在集群中状态情况就会增多。

二、Kafka 和 RocketMQ 的分布式解读

我们先看看比 rocketmq 更让人熟知的大师兄 Kafka,解读一下 Kafka 集群的分布式特点。



Kafka 的集群管理来自 zookeeper 集群,Broker 的注册发现,Broker Controller 的选举都是由 zookeeper 来协助完成,但是 Controller 其实也不在消息处理时做什么事情,只是在创建分区、分区再平衡等方面对其他节点做领导性工作。

Kafka 真正起作用的还是分区 leader 和分区 follower。例如:一个 topic 会被分成 4 个分区,3 个副本,那么一共 4*3=12 个分区副本,若有 4 个 broker,那么每个 broker 就会以一主两从,放置三个分区的形式均匀分布。



Kafka 的分区关系就是上图这个通讯形式,生产者(Product)从任意节点获取 Meta 信息,找到 broker 中的 leader 分区副本,会向里面写分配好的数据,leader 会向集群中其他 broker 的 follower 分区副本复制一份。

在这种分区结构关系下,其实每个 broker 都具有了 topic 分区数据请求访问以及副本复制的 Master 能力。所以你问我 kafka 是不是中心模式,下来再说。

我们再看看 kafka 的阿里兄弟 rocketmq

rocketmq 的架构已经不使用 zookeeper 集群作为服务的注册发现了



rocketmq 队列模式很大程度上与 kafka 非常像,但是具体操作细节上有自己的特点,更符合高并发的,更多 topic 的,有顺序要求的业务消息处理,例如 Topic 进行了多个分片划分,分区又进行了多个 Queue 的划分,每个 Queue 只能对应一个消费者,来实现更高并发的消费端均衡负载。具体细节这就不赘述了。我们主要还是看看 rocketmq 的分布式特征。

其实 NameServer 也就是做了一个 broker 的注册表,新注册 broker 或者异常退出 broker 都向对应的 NameSever 汇报或感知,NameServer 之间是无中心的,大家通过锁注册表的方式共享信息,NameServer 增加/删除所辖 broker 到这个注册表,并定时读取最新的集群所有 broker 信息。

生产者(Producet)连接上一个 NameServer,就能获取到想要的发送分区数据的 brokers,消费者同理,发送消费的这个过程很类似 Kafka 操作 topic,只是更细致到 topic 下的 queue 这个级别。

rocketmq 还有一个特点是每个 borker 可以再分成主从模式,master 进行队列操作,slave 只做数据同步,等待 master 出现故障进行替换。

rocketmq 的 namesever 相对于 zookeeper 具有更简单的结构,生产者和消费者对 broker 以及分区的获取必须来自 namesever,尽管 namesever 集群本身是无中心的,但整个 rocketmq 的 brokers 就是被 namesever 中心化管理的,但整体上 product、consumer、brokers 集群对这种集中管理的依赖程度其实不高,只是提供了很简单的 broker 元信息服务,真正的数据流还是交给各个 broker 自己去解决。

kafka 的 broker 分区信息是分布在每一台 broker 的 meta 缓存里面,生产者和消费者可以在任意一台 borker 上获取需要操作的 leader 分区信息,kafka 这就有点去中心的意思。然而这些 meta 缓存信息实质是来自 zookeeper,zookeeper 是必须依赖的,所以本质上 Kafka 依然是中心化管理。

oceanbase 分布式架构

oceanbase 是 LSM-Tree 的一个典型实现,对于 LSM-Tree 可以看我的另一篇针对 TiDB 的回答文章中,主要对 RocksDB 的 LSM-Tree 的特征做了描述: 为什么分布式数据库这么喜欢用 kv store?

作为 oceanbase 的架构,这次就不说太多了,就是想简单总结一下,oceanbase 架构非常巧妙地融入了 Lambda 架构思想,但又和 Lambda 架构思想的关注点不同,Lambda 架构关注的是计算,而 oceanbase 是存储。



oceanbase 往往 rootServer、updateServer 部署在一个节点,共同承担了分布式中心的作用。

rootServer 用于管理集群

updateServer 用于增量数据更新,尽量在内存中完成增量,形成最高效的近期增量数据查询,往往是当天数据。

chunkServer 用于基线数据存储,实际情况往往是隔天历史数据。

mergeServer,接受客户端的 SQL 进行解释,并且对 updateServer 查询结果、不同 chunkServer 节点查询结果数据合并,往往是当天增量数据和隔天历史数据的查询与合并。

这与 Lambda 架构的速度层、批量层、服务层的思想非常类似。当客户发起查询统计请求,updateServer 满足当天增量数据的实时查询统计,chunkServer 节点提供基线数据的分布式查询,最终由 mergeServer 对 updateServer 当日结果和各 chunkServer 基线结果进行合并后,反馈给客户端,总之 oceanbase 架构设计是个艺术品。

总结

这篇文章主要是介绍了分布式中 redis cluster 去中心化管理,kafka 与 rocketmq 中心化管理的架构特点,顺便提了一些 oceanbase 的架构特色。

消息队列架构对于集中模式的依赖很轻,rocketmq 也只是简单粗暴地使用了 nameserver,用于 broker 注册发现,我认为 kafka 完全可以在将来的设计取消 zookeeper,用更为去中心化的思路来设计注册和发现。

反观 redis 最成熟的方案还是主从,redis cluster 带来的性能优势无法抵消去中心化带来的不成熟和不可靠问题,导致人工运维的复杂度和难度。所以 redis cluster 慎用!

oceanbase 的架构很优雅也很艺术,抽时间好好再理解实践写一篇,oceanbase 类似 Google 的 Bigtable,Hadoop 的 Hbase,只是在其之上融入了 Lambda 架构的思想。让系统表现得更符合实际需求,也更为灵活可靠。但集群对资源需求不少。


我是“读字节”创作者,深入大数据技术、解读分布式架构

前往读字节的知乎——了解更多关于大数据的知识

https://www.zhihu.com/people/fangshun/answers

公众号 read-byte “读字节” 大数据,分布式软件架构的深度,专业解读


发布于: 2021 年 03 月 14 日阅读数: 21
用户头像

读字节

关注

公号“读字节”大数据、软件架构的深入解读 2018.05.29 加入

西安守护石信息科技 创始人 方顺

评论

发布
暂无评论
四款面向高并发、海量级分布式存储的分布式架构对比