Kafka涉及到的多种选举机制

提起Kafka中的选举,第一印象肯定是broker节点之间的选举,它依赖于Zookeeper来进行选举,其实还有partition之间也有选举,以及其他地方都存在选举,但这些都是由Kafka内部完成,它们都需要一个leader来把控全场,由leader来负责读写请求,处理消息的同步,监听分区变化,监听主题变化,保存一些分区方案,记录消费位移等信息。我总结的有以下几种选举。

使用CyclicBarrier控制Kafka多线程消费消息的位移提交问题

Kafka中消费者是线程不安全的,一个topic只能被一个消费组中的消费者消费,想要提高数据消费能力,可以增加分区数,因为消费者数可以和分区数进行对应,当消费者数大于分区数时,多余的消费者将处于空闲状态,或者也可以在每个线程中创建一个消费者实例,这样也可以对数据来处理,但创建多个消费者实例必然会造成资源的浪费。通过线程池来对数据进行消费,就会存在位移提交的问题,从而引发数据丢失或重复,所以对位移的提交要格外处理,消费者默认是定时提交位移信息的,如果需要手动提交,要先修改配置参数关闭自动提交,再通过代码里调用commitSync()方法。

从TheadLocalMap看哈希碰撞后开放寻址法的实现过程

本来想说ThreadLocal,但看到了ThreadLocalMap中对哈希碰撞是采用开放寻址法来实现的,觉得很有意思,hash使用的场景很多,散列表就是一种高效而常用的数据结构,能将查找的时间复杂度降到O(1),它通过哈希函数来生成一个 hashcode 值,从而对数据进行一一定位,虽然现在的哈希函数已经能做到很好的随机,但还是会有冲突发生,也就是不同的对象经过哈希函数的计算,生成了相同的 hashcode 值。当哈希冲突发生时,一般有以下几种方式来处理:

分布式锁实践中的一些坑及优化手段

当微服务由单机部署变为分布式集群部署,在业务中涉及的一些数据库操作或者其他可能存在并发问题的地方,都有可能因为代码层面考虑不周或存在漏洞,导致数据丢失更新,数据不一致的问题发生,我也是在工作中遇到这个问题。例如A请求查询数据库中可用次数为100,此时B请求也查询数据库中可用次数为100,A请求进行-1之后在数据库中修改为99,而B请求也-1之后修改数据库中可用次数为99,这时就发生了数据丢失更新的问题,给公司造成了损失,当并发量更大,B请求出现一定延时,可能会发生其他请求已经修改了十多次,而B请求又将可用次数改为99,如此日积月累会造成巨大的损失。

我由幻读而明白了数据库事务

innodb更加完美的解决了幻象问题,在默认情况下设置为REPEATABLE-READ的隔离级别即可,事务级别越低涉及到的锁越少,虽然REPEATABLE-READ级别会将Record Lock升级为Next-key lock锁,但并不会比READ-COMMITTED级别有性能损耗。

Kafka中再均衡的发生过程

Kafka中消费者以消费组的形式存在,消费组来消费每个主题中分区的数据,因为主题中的分区数和消费者数量并不一一对应,这时候就涉及到如何为每个消费者分配分区,而当有消费者在中途退出时,就会触发再均衡的发生,再重新为剩余的消费者分配分区。每个消费组在服务端对应一个GroupCoordinator对其进行管理,而消费者客户端中的ConsumerCoordinator组件负责与GroupCoordinator进行交互,它们负责执行分区的分配,以及消费者再均衡的操作。

浅析微服务注册中心的注册与发现

注册中心是用来集中管理微服务,实现服务的注册,发现,检查等功能,目前比较成熟的注册中心组件有很多,如Consul,eureka,zookeeper,etcd,nacos,不同组件之间性能,并发,高可用都会有差距。但对于用户来说基本的功能实现都是透明的。其实如果我们自己开发一套注册中心也可以,能够满足基本的功能即可。

Kafka实现订单超时取消的两种模拟策略

在业务场景中有一个需要定时15分钟后取消用户订单的功能,可以使用Java的任务调度框架来实现,但还需要引入框架依赖和设置数据表等,对业务的侵入性很大,有点大材小用的感觉,所以这里使用延时队列就可以,Kafka本身是不支持延时队列的,需要在生产消息和消费时进行一些二次开发,以下是我对该业务具体实现的思考。

对于mysql,redis,Kafka,zookeeper磁盘缓存技术使用分析

大部分组件是基于磁盘存储的,但由于CPU速度和磁盘速度之间的鸿沟,都会使用缓存技术来提高性能,缓存简单来说就是一块内存区域,首先将从磁盘读到的数据放在缓存中,之后查询或修改时直接操作缓存,对于缓存中的数据则以一定的频率刷新到磁盘上,怎样缓存,缓存多少,何时刷新,这些影响着整个组件的性能。在看过一些关于mysql等组件的架构原理后,会发现不论是基于磁盘的mysql数据库和Kafka消息中间件zookeeper分布式协调框架,还是基于内存的redis数据库,它们都设计了完善的内存和磁盘之间数据交互实现。

分布式锁的锁优化

在去除原有synchronized单机锁后,在关键步骤添加分布式锁来对具体业务进行锁定,然而由于锁定范围大,导致锁竞争增加,不断发生锁等待,如果不进行优化,可能会让线程队列增大甚至阻塞,而且在等待时长超过设定的阈值时,线程将超时返回。