Redis并发竞争key的解决方案详解
1. 需求由来
1.Redis高并发的问题
Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题:缓存击穿、缓存雪崩、缓存和数据一致性,以及今天要谈到的缓存并发竞争。
这里的并发指的是多个redis的client同时set key引起的并发问题。
2.出现并发设置Key的原因
Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以Redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对Redis进行并发访问时会出现问题。
比如:同时有多个子系统去set一个key。这个时候要注意什么呢?
3.举一个例子
多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,最后是4,但是顺序变成了4,3,2,最后变成了2。

2. 解决方案
- 第一种方案:分布式锁+时间戳
1.整体技术方案
这种情况,主要是准备一个分布式锁,大家去抢锁,抢到锁就做set操作。
加锁的目的实际上就是把并行读写改成串行读写的方式,从而来避免资源竞争。
2.Redis分布式锁的实现
主要用到的redis函数是setnx()
用SETNX实现分布式锁。利用SETNX非常简单地实现分布式锁。例如:某客户端要获得一个名字youzhi的锁,客户端使用下面的命令进行获取:
SETNX lock.youzhi<current Unix time + lock timeout + 1>
如返回1,则该客户端获得锁,把lock.youzhi的键值设置为时间值表示该键已被锁定,该客户端最后可以通过DEL lock.foo来释放该锁。
如返回0,表明该锁已被其他客户端取得,这时我们可以先返回或进行重试等对方完成或等待锁超时。
3.时间戳
由于上面举的例子,要求key的操作需要顺序执行,所以需要保存一个时间戳判断set顺序。
系统A key 1 {ValueA 7:00}
系统B key 1 { ValueB 7:05}
假设系统B先抢到锁,将key1设置为{ValueB 7:05}。接下来系统A抢到锁,发现自己的key1的时间戳早于缓存中的时间戳(7:00<7:05),那就不做set操作了。
4.分布式锁
因为传统的加锁的做法(如java的synchronized和Lock)这里没用,只适合单点。因为这是分布式环境,需要的是分布式锁。
当然,分布式锁可以基于很多种方式实现,比如zookeeper、redis等,不管哪种方式实现,基本原理是不变的:用一个状态值表示锁,对锁的占用和释放通过状态值来标识。
- 第二种方案:利用消息队列
在并发量过大的情况下,可以通过消息中间件进行处理,把并行读写进行串行化。
把Redis.set操作放在队列中使其串行化,必须的一个一个执行。
这种方式在一些高并发的场景中算是一种通用的解决方案。
转载知乎https://zhuanlan.zhihu.com/p/52756935
Redis并发竞争key的解决方案详解的更多相关文章
- 高并发架构系列:Redis并发竞争key的解决方案详解
https://blog.csdn.net/ChenRui_yz/article/details/85096418 https://blog.csdn.net/ChenRui_yz/article/l ...
- 分布式-技术专区-Redis并发竞争key的解决方案详解
Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题:缓存击穿.缓存雪崩.缓存和数据一致性,以及今天要谈到的缓存并发竞争.这里的并发指的是多个redis的clie ...
- Redis缓存穿透、缓存雪崩、redis并发问题 并发竞争key的解决方案 (阿里)
阿里的人问我 缓存雪崩(大量数据在同一时间过期了)了如何处理,缓存击穿了如何处理,回答的很烂,做了总结: 把redis作为缓存使用已经是司空见惯,但是使用redis后也可能会碰到一系列的问题,尤其是数 ...
- Redis并发竞争
Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘.由于单线程所以Redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对Redi ...
- C++11 并发指南六( <atomic> 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- C++11 并发指南五(std::condition_variable 详解)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
- Redis for Windows(C#缓存)配置文件详解
Redis for Windows(C#缓存)配置文件详解 前言 在上一篇文章中主要介绍了Redis在Windows平台下的下载安装和简单使用http://www.cnblogs.com/aehy ...
- redis使用及配置之缓存详解
redis使用及配置之缓存详解 1.Redis的介绍 Redis是一个Key-Value存储系统.它支持存储的value类型有:string(字符串),list(链表), set(无序集合),zset ...
- redis cluster管理工具redis-trib.rb详解
redis cluster管理工具redis-trib.rb详解 来源 http://weizijun.cn/2016/01/08/redis%20cluster%E7%AE%A1%E7%90%86% ...
随机推荐
- CentOS 8.2远程连接vncserver升级后1.10.1无法启动解决记录
CentOS 8.2远程连接vncserver升级后1.10.1无法启动解决记录 问题起源:手贱yum upgrade,重启服务器后无法使用vnc viewer远程连接 查看状态 # system ...
- IT菜鸟之虚拟机VMware的使用
虚拟机安装完成了,以下是虚拟机的使用. 双击快捷方式,打开vmware虚拟机. 点击创建新虚拟机,这里可以选择创建方式,可以点击典型并一路下一步创建,我们这里讲自定义创建. 这里选择兼容版本,大家可以 ...
- shell 读取某个目录下的所有文件
#!/bin/shFILE_PATH="xxx" xxx:路径cd $FILE_PATHfor FILE in `ls` do echo $FILE done
- TCP三次握手和四次挥手及对应端口状态
一.三次握手 1.第一次握手:Client 将标志位置为1,并向Server发送个seq=j,j为随机产生的数:等待Server回复,此时Client的端口状态为SYN_SENT. 2.第二次握手:S ...
- IDEA 查看类图功能(分析源码的利器)
引言 做过项目开发的童靴,应该会有这样的经历,就是刚进公司领导二话不说直接丢个项目,而且没有任何文档,让熟悉一下,一两周就让上手写代码.打开项目后就看到一堆类源码,完全不知道从何处入手,应该如何分析项 ...
- 西门子 S7200 以太网模块连接组态王方法
北京华科远创科技有限研发的远创智控ETH-YC模块,以太网通讯模块型号有MPI-ETH-YC01和PPI-ETH-YC01,适用于西门子S7-200/S7-300/S7-400.SMART S7-20 ...
- python实现发送微信消息
import json from threading import Timer from wxpy import * import requests import urllib.parse def g ...
- THINKPHP_(2)_TP模型的多表关联查询和多表字段的关键字搜索。
问题: 上述内容中,标题和学年属于一个数据表.分类则属于另外一个数据表,并且是利用id关联后,另外一个数据表中的title字段. 需要设置关键字搜索,实现多表关联查询和多表字段的关键字搜索. 解决方法 ...
- CVPR 2020目标跟踪多篇开源论文(下)
CVPR 2020目标跟踪多篇开源论文(下) 6. Cooling-Shrinking Attack: Blinding the Tracker with Imperceptible Noises 作 ...
- MindSpore应用目标
MindSpore应用目标 以下将展示MindSpore近一年的高阶计划,会根据用户的反馈诉求,持续调整计划的优先级. 总体而言,会努力在以下几个方面不断改进. 1. 提供更多的预置模型支持. 2. ...