能够参考数据库乐观锁机制,好比执行一条更新库存的 SQL 语句,在并发场景,为了性能和数据可靠性,会在更新时加上查询时的版本,而且更新这个版本信息。可能你要对一个事情进行操做,这个操做可能会执行成百上千次,可是操做结果都是相同的,这就是幂等性。redis
在海量订单生成的业务高峰期,生产端有可能就会重复发生了消息,这时候消费端就要实现幂等性,这就意味着咱们的消息永远不会被消费屡次,即便咱们收到了同样的消息。算法
1.惟一 ID + 指纹码 机制,利用数据库主键去重
2.利用redis的原子性去实现
复制代码
你们确定懂惟一 ID 的,就很少说了,为何须要指纹码呢?这是为了应对用户在一瞬间的频繁操做,这个指纹码多是咱们的一些规则或者时间戳加别的服务给到的惟一信息码,它并不必定是咱们系统生成的,基本都是由咱们的业务规则拼接而来,可是必定要保证惟一性,而后就利用查询语句进行判断这个id是否存在数据库中。数据库
好处就是实现简单,就一个拼接,而后查询判断是否重复。缓存
坏处就是在高并发时,若是是单个数据库就会有写入性能瓶颈并发
解决方案 :根据 ID 进行分库分表,对 id 进行算法路由,落到一个具体的数据库,而后当这个 id 第二次来又会落到这个数据库,这时候就像我单库时的查重同样了。利用算法路由把单库的幂等变成多库的幂等,分摊数据流量压力,提升性能。高并发
相信你们都知道 redis 的原子性操做,我这里就不须要过多介绍了。工具
使用 redis 的原子性去实现须要考虑两个点性能
一是 是否 要进行数据落库,若是落库的话,关键解决的问题是数据库和缓存如何作到原子性? 数据库与缓存进行同步确定要进行写操做,到底先写 redis 仍是先写数据库,这是个问题,涉及到缓存更新与淘汰的问题spa
二是若是不落库,那么都存储到缓存中,如何设置定时同步的策略? 不入库的话,可使用双重缓存等策略,保障一个消息副本,具体同步可使用相似 databus 这种同步工具。code