怎么确保消费者收到音信的次第

Redis的7个利用场景

背景

事先面试的时候被问到关于mq怎样确保信息的逐条问题,当时没回复好,网上也没找到如意的答案,于是自己想了一个

 

题材讲述

一经,A和B通过新闻队列通信,A发了程序发了2条音讯m1和m2。A发出的相继是m1、m2,结果m2先到达队列,m1后进的,那么在队列中m2在前m1在后,假使这两条音信是有依靠关系的,必须是先m1再m2,那么B可能先接受到m2后吸收到m1,问这些时候如何是好?

图片 1

我的沉思

1、B接收到音信的次第跟A发出信息的先后顺序以及音信在队列中的顺序是不曾关联的。音讯到达队列的先后顺序没法保证,同样,队列将音讯投递出去之后收到音讯的一一也无可奈何保证,所以,我想无论咋样作为消费者的B都不可能不确保工作的不易,无论生产者怎么怎么发消息,队列怎么投递音信,作为消费者都不可以不意识到:接收到的音讯是无序的,必须抓好处理,务必确保工作正常。

2、我觉着这是一个通用的题材,也是作为消费者必须要考虑的问题

3、信息的相继并不根本,重要的是要保管工作的最终一致性

一:缓存——热数据

化解方案

人心向背数据(通常会被询问,然则不通常被修改或者去除的多少),首选是行使redis缓存,毕竟强大到冒泡的QPS和极强的安澜不是具备类似工具都有的,而且比较于memcached还提供了增长的数据类型可以使用,此外,内存中的数据也提供了AOF和RDB等持久化机制得以挑选,要冷、热的如故忽冷忽热的都可选。

方案一:本地音信表+定时扫描

1、接收到消息之后,将信息保存到地头数据库的表中,标记为未处理

2、若满意处理规范,直接处理,成功将来,标记表中的记录为已处理,然后向队列确认音讯

3、若不满意处理原则,则暂不处理

4、定时扫描本地音讯表,将这个未处理的再过一次

5、幂等性判断很要紧

构成实际运用需要小心一下:很四个人用spring的AOP来构建redis缓存的自动生产和消除,过程可能如下:

举个栗子

设若,签到送积分。

再假诺,签到和送积分是分手的,签到的逻辑是向签到表中插入一条记下,送积分的逻辑是判定积分所对应的登录记录是否存在,存在则送积分,否则不送。

继而即使,信息队列中有两条消息,一条是签到音信,另一条是送积分信息,这条积分信息带着签到记录的id。

那么,送积分的时候将要借助是否有记名记录。依照下边的申辩,将音讯先保存在地头,然后定时扫描,是足以正常举办的。

 

~水平有限,暂时只想到这种措施,欢迎批评指正!!!~

 

  • Select 数据库前查询redis,有的话使用redis数据,放弃select
    数据库,没有的话,select 数据库,然后将数据插入redis

  • update或者delete数据库钱,查询redis是否留存该数据,存在的话先删除redis中数据,然后再update或者delete数据库中的数据

地点这种操作,如若并发量很小的情状下核心没问题,不过高并发的情况请小心下边场景:

为了update先删掉了redis中的该多少,这时候另一个线程执行查询,发现redis中从未,刹那间执行了查询SQL,并且插入到redis中一条数据,回到刚才不行update语句,这多少个悲催的线程压根不通晓刚刚可怜该死的select线程犯了一个弥天大错!于是这些redis中的错误数据就永远的留存了下来,直到下一个update或者delete。

二:计数器

譬如说总计点击数等利用。由于单线程,可以避免出现问题,保证不会出错,而且100%皮秒级性能!爽。

命令:INCRBY

本来爽完了,别忘记持久化,毕竟是redis只是存了内存!


三:队列

  • 约等于音讯系统,ActiveMQ,RocketMQ等工具类似,不过个人觉得简单用一下还行,假如对于数据一致性要求高的话依然用RocketMQ等正规系统。

  • 出于redis把数据增长到行列是回到添先令素在队列的第几位,所以可以做判定用户是第几个访问这种业务

  • 队列不仅可以把并发请求变成串行,并且还足以做队列或者栈使用


四:位操作(大数据处理)

用于数据量上亿的面貌下,例如几亿用户系统的记名,去重登录次数总结,某用户是否在线状态等等。

思想一下腾讯10亿用户,要多少个皮秒内查询到某个用户是否在线,你能怎么办?千万别说给每个用户建立一个key,然后挨个记(你可以算一下急需的内存会很害怕,而且这体系似的要求很多,腾讯光这多少个得多花多少钱。。)好吗。这里要用到位操作——使用setbit、getbit、bitcount命令。

原理是:

redis内构建一个足足长的数组,每个数组元素只可以是0和1五个值,然后这个数组的下标index用来表示我们地点例子里面的用户id(必须是数字哈),那么很显著,这些几亿长的大数组就能透过下标和元素值(0和1)来构建一个记念系统,上边我说的多少个现象也就可知实现。用到的命令是:setbit、getbit、bitcount


五:分布式锁与单线程机制

  • 表明前端的双重请求(可以任意扩展类似情况),可以经过redis举行过滤:每一回请求将request
    Ip、参数、接口等hash作为key存储redis(幂等性请求),设置多短时间有效期,然后下次恳请过来的时候先在redis中检索有没有其一key,进而证实是不是早晚时间内回升的再次提交

  • 秒杀系统,基于redis是单线程特征,制止出现数据库“爆破”

  • 全局增量ID生成,类似“秒杀”


六:最新列表

例如音信列表页面最新的新闻列表,固然总数量很大的情景下,尽量不要使用select
a from A limit 10那种low货,尝试redis的
LPUSH命令构建List,一个个逐个都塞进去就足以啦。不过只要内存清掉了咋做?也简单,查询不到存储key的话,用mysql查询并且起始化一个List到redis中就好了。


七:排行榜

什么人得分高什么人名次往上。命令:ZADD(有续集,sorted set)

近些年在琢磨股票,发现量化交易是个可怜好的点子,通过估计出来规律,用程序对历史数据举行表明,来判定这多少个推测出来的原理是否可行,这玩意儿真牛!有没有哪位玩这一个的给本人留个言,交换一下呗。