消息队列与数据库

  • Kafka架构原理【1】:
kafka架构
kafka架构

1、消费模式:producer使用push模式,consumer使用pull模式。

tips:如果采用 Push,消息消费的速率就完全由消费代理控制,一旦消费者发生阻塞,就会出现问题。

Kafka 采取拉取模型(Pull),由自己控制消费速度,以及消费的进度,消费者可以按照任意的偏移量进行消费。

2、broker和consumer使用zookeeper,producer可以指定多个broker的url,producer通过broker获取整个集群的broker列表信息,将broker源信息存入producer内存中。

producer刷新broker源信息的触发方式:

1)producer向broker发送失败时出发重新获取broker源信息;

2)配置周期性刷新;

3、Topic 和 Partition:每一条消息都有一个 topic,Kafka 为每个主题维护了分布式的分区(Partition)日志文件,分区的目的是为了做负载均衡。

KAFKA维护一个Topic中的分区log,以顺序追加的方式向各个分区中写入消息,每个分区都是不可变的消息队列。分区中的消息都是以k-v形式存在。k表示offset,称之为偏移量,一个64位整型的唯一标识,offset代表了Topic分区中所有消息流中该消息的起始字节位置。v就是实际的消息内容,每个分区中的每个offset都是唯一存在的,所有分区的消息都是一次写入,在消息未过期之前都可以调整offset来实现多次读取。

生产者会决定发送到哪个 Partition,如果没有 Key 值则进行轮询发送;如果有 Key 值,对 Key 值进行 Hash,然后对分区数量取余,保证了同一个 Key 值的会被路由到同一个分区。对于分区可以有副本机制保证高可用。

4、幂等性:每个 Producer 在初始化的时候都会被分配一个唯一的 PID,对于每个唯一的 PID,Producer 向指定的 Topic 中某个特定的 Partition 发送的消息都会携带一个从 0 单调递增的 Sequence Number。

如果消息序号比 Broker 维护的序号大一以上,说明中间有数据尚未写入,也即乱序,此时 Broker 拒绝该消息,Producer 抛出 InvalidSequenceNumber。

如果消息序号小于等于 Broker 维护的序号,说明该消息已被保存,即为重复消息,Broker 直接丢弃该消息,Producer 抛出 DuplicateSequenceNumber。

如果消息序号刚好大一,就证明是合法的。

5、事务:上面所说的都是在同一个 PID 下面,意味着必须保证在单个 Producer 中的同一个 Seesion 内,如果 Producer 挂了,被分配了新的 PID,这样就无法保证了,所以 Kafka 中又有事务机制去保证。

1)在 Kafka 的事务中,应用程序必须提供一个唯一的事务 ID,即 Transaction ID,并且宕机重启之后,也不会发生改变。Transactin ID 与 PID 可能一一对应,区别在于 Transaction ID 由用户提供,而 PID 是内部的实现对用户透明。

2)为了 Producer 重启之后,旧的 Producer 具有相同的 Transaction ID 失效,每次 Producer 通过 Transaction ID 拿到 PID 的同时,还会获取一个单调递增的 Epoch。由于旧的 Producer 的 Epoch 比新 Producer 的 Epoch 小,Kafka 可以很容易识别出该 Producer 是老的,Producer 并拒绝其请求。

3)该 Transaction Coordinator 服务器端的模块用于管理 Producer 发送的消息的事务性,作用是保证操作的原子性,要么全部成功,要么全部失败;有状态的操作的恢复。通过维护 Transaction Log,该 Log 存于一个内部的 Topic 内。Transaction Log 的设计与 Offset Log 用于保存 Consumer 的 Offset 类似。

  • Kafka高性能【2】:

1、消息顺序写入磁盘。

2、消息集合在一起批量发送,这样减少对磁盘IO的过度读写,而不是一次发送单个消息。

3、KAFKA采用由Producer,broker和consumer共享的标准化二进制消息格式,这样数据块就可以在它们之间自由传输,无需转换,降低了字节复制的成本开销。

4、Kafka重度依赖底层操作系统提供的PageCache功能。当上层有写操作时,操作系统只是将数据写入PageCache,同时标记Page属性为Dirty。当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。

5、sendfile,只需要一次拷贝就行:允许操作系统将数据直接从页缓存发送到网络上。

这种页缓存和sendfile组合,意味着KAFKA集群的消费者大多数都完全从缓存消费消息,而磁盘没有任何读取活动。

6、批量压缩,批量的消息可以通过压缩的形式传输并且在日志中也可以保持压缩格式,直到被消费者解压缩。

  • mysql锁机制【3】:

MyISAM表锁:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock),MyISAM默认加锁。默认允许没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。

InnoDB锁:一是支持事务(TRANSACTION);二是采用了行级锁。

1、行级锁:共享锁(s):

1)又称读锁、排他锁(X):又称写锁;

2)如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT… FOR UPDATE方式获得排他锁;

3)只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁! 

2、间隙锁(Next-Key锁)

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁

 

 

【1】https://www.jianshu.com/p/4bf007885116    《Kafka的架构原理,你真的理解吗?》

【2】http://rdcqii.hundsun.com/portal/article/709.html    《KAFKA:如何做到1秒发布百万级条消息》

【3】https://www.cnblogs.com/leedaily/p/8378779.html    《Mysql中的锁机制》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章