kafka rebalance
kafka rebalance Kafka session.timeout.ms heartbeat.interval.ms 参数的区别以及对数据存储的一些思考 在计算机世界中经常需要与数据打交道,这也是我们戏称 CURD 工程师的原因之一。写了两年代码,接触了不少存储系统,Redis、MySQL、Kafka、Elasticsearch 慢慢地发现背后的一些公共的设计思想总是那么似曾相识,再深究一下,就会发现一些隐藏在这些系统背后的数学理论。 生活中产生的大量数据需要交由计算机来处理,根据处理方式的不同分为 OLTP 和 OLAP 两大类应用。有些数据比如登录流水、系统日志信息,源源不断, 先采集下来抛给消息中间件(Kafka);有些数据,比如一条描述用户特征的记录,就适合存储到 MySQL,并按日期建查询索引。也就是说:面对大量的数据, 把数据存储起来只是一小步,重要的是如何把这些数据用起来,体现到存储系统则是:有没有一套方便的查询接口能够方便快速地查到我们想要的数据。 如果将数据放到 Kafka上了,那要怎么查?如果把数据放到 MySQL 上了,非常适合针对高 cardinality 列建 B+ 树索引查询,而对于文本类的数据,放到 ES 上, 则基于倒排索引这种数据结构,根据 tf-idf、bm25 等这些衡量文档相似度的算法来快速地获得想要的数据。 从这也可以看出,不同的存储系统,为了满足"查询",它们背后的存储原理(所采用的数据结构)是不同的。而对于这些存储系统而言,都面临着两个问题: 高可靠性和高可用性。可靠性,在我看来,是站在存储系统本身来看,一般是讨论单个实例如何保证数据的可靠。 比如,一个正在运行的MySQL实例,它根据checkpoint机制,通过redo log 文件来保证持久性,另外还有double write buffer,保证数据页的写入是可靠的。 类似地,在 Elasticsearch 里面也有 translog 机制,用来保证数据的可靠性。所以,想深入了解存储系统,不妨对比一下它们之间的各种 checkpoint 机制。 数据为什么需要有可靠性呢?根本原因还是内存是一种易失性存储,根据冯偌依曼体系结构,程序总是从内存中取数据交给CPU做运算。如果数据没有fsync到磁盘, 如果系统宕机那数据会不会丢? 而对于可用性,是从Client角度而言的。即我不管你背后是一个redis实例还是一个redis 集群,你只管正常地给我提供好读写服务就好了。这里为了避免SPOF, 分布式集群就派上用场了,一台机器挂了,另一台机器顶上。在分布式系统中,需要管理好各个存储实例,这时就需要节点的角色划分,比如master节点、controller节点之类的称呼。 毕竟管理是要有层级的嘛,大家角色都一样,怎么管理呢?在这一点上,Redis集群与Kafka集群或者Elasticsearch集群有很大的不同, 具体体现在Redis本质上是一个P2P结构的集群,而Elasticsearch和Kafka 采用的主从模型,为什么这么说呢?Redis虽然也有Master节点和Slave节点之分, 但它的各个Master节点之间是平等的,Redis的数据分布方式是hash16384个槽到各个master节点上,每个master节点负责处理落在这些槽内的数据, 这是从数据分布的角度来定义的Master节点,而Kafka中的Controller节点、Elasticsearch中的master节点并不是从数据分布的角度定义的,而是从集群元信息维护、 集群管理的角度定义的,关于它们之间的具体区别我在这篇文章中也有过一些描述。另外,MySQL作为关系型数据库,受数据完整性约束、事务支持的限制,在分布式集群能力上要弱一些。 最近碰到一个问题,多个业务往向一个 Kafka topic 发送消息,有些业务的消费量很大,有些业务的消息量很小。因 Kafka 尚未较好地支持按优先级来消费消息, 导致某些业务的消息消费延时的问题。一种简单的解决方案是再增加几个Topic,面对一些系统遗留问题,增加Topic带来的是生产者和消费者处理逻辑复杂性。 一种方法是使用Kafka Standalone consumer,先使用 consumer.partitionFor(“TOPIC_NAME”) 获取 topic 下的所有分区信息, 再使用consumer.assign(partitions)显示地为consumer指定消费分区。另一种方法是基于 consumer group 自定义 Kafka consumer 的分区分配策略, 那这时候就得对Kafka目前已有的分区分配策略有所了解,并且明白什么时候、什么场景下触发 rebalance? ...