基于异步消息队列List lpush-brpop(rpush-blpop)

基于异步消息队列List lpush-brpop(rpush-blpop),第1张

使用rpush和lpush *** 作入队列,lpop和rpop *** 作出队列。

List支持多个生产者和消费者并发进出消息,每个消费者拿到都是不同的列表元素。

但是当队列为空时,lpop和rpop会一直空轮训,消耗资源;所以引入阻塞读blpop和brpop(b代表blocking),阻塞读在队列没有数据的时候进入休眠状态,

一旦数据到来则立刻醒过来,消息延迟几乎为零。

注意

你以为上面的方案很完美?还有个问题需要解决:空闲连接的问题。

如果线程一直阻塞在那里,Redis客户端的连接就成了闲置连接,闲置过久,服务器一般会主动断开连接,减少闲置资源占用,这个时候blpop和brpop或抛出异常,

所以在编写客户端消费者的时候要小心,如果捕获到异常,还有重试。

缺点:

做消费者确认ACK麻烦,不能保证消费者消费消息后是否成功处理的问题(宕机或处理异常等),通常需要维护一个Pending列表,保证消息处理确认。

不能做广播模式,如pub/sub,消息发布/订阅模型

不能重复消费,一旦消费就会被删除

不支持分组消费

问题现状

某系统, 订单单表早就已经突破200G ,由于查询维度较多,即使加了 两个从库,优化索引 等优化手段也无济于事。因为数据库达到瓶颈,应用只能通过 限速、异步队列等对其进行保护, 因此进行分库分表的尝试

整体思路

按照商户ID进行分库,用户ID进行分表,同时通过数据同步等方式,把数据同步到一个运营库, 同时满足C端用户、B端商户、客服、运营等的需求。最终,通过 新老系统双写 逐渐从老库过渡到新库,完成业务的切换。

切分策略

1. 查询切分

将ID和库的Mapping关系记录在一个单独的库中,但是这样 引入额外的服务器来维护这个Mapping关系

2. 范围切分

按照时间区间或ID区间来切分。但是 针对于某些大商户来说,还是解决不了性能瓶颈的问题

3. Hash切分(最终方案)

我们分库分表的方案是16*16的。

商户Id后四位mod 16 分16个库, UserId后四位Mod 16 将每个库分为16个表,共计分为256张表。

线上部署情况为 4个集群 ,每个集群4个库( 1主3从 )。

场景一:数据库性能达到瓶颈:扩大数据库的集群数量,从16个数据库变成32个数据库。

场景二:单表容量达到瓶颈:扩大分表的数量,从16切分变成32切分。

唯一ID方案

1. 利用数据库自增ID(单点风险、单机性能瓶颈)

2. 利用数据库集群并设置相应的步长(需要单独的数据库集群)

3. Twitter Snowflake(需要独立的集群以及ZK)

4.采用了带有业务属性的方案:(时间戳+商户ID+用户ID+随机数)

其他问题

数据迁移

第一阶段

第二阶段

第三阶段

总结


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6636495.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-26
下一篇 2023-03-26

发表评论

登录后才能评论

评论列表(0条)

保存