Redis一文精通
set
setnx
setex
redisson加锁过程:
同一线程加锁(lua脚本),其他线程不能加锁,同一线程可以重新加锁(可重入锁lua脚本),定时对该线程进行锁续期(监听器,续期是lua脚本)。
lua脚本:因为redis在2.6版本之后,支持lua脚本进行批量处理,redis将其脚本执行变成原子性操作。
redisson:lock底层用的是hset
lua脚本里面描述了一下信息:
第一次加锁:exists hset pexpire
第二次重入锁:hexists hincrby pexpire
redisson是如何保证锁续期的幂等性?
Redisson在锁续期的实现上,采用了一种乐观锁的方式来保证其幂等性。
具体来说,当一个Redisson锁需要进行续期操作时,会向Redis服务器发送一条续期命令,该命令会携带当前持有锁的线程标识和续期时间。Redis服务器会首先检查当前锁的持有者是否为该线程,并且锁的剩余过期时间是否小于当前请求的续期时间。如果满足这两个条件,说明当前请求是有效的,Redis服务器会将锁的过期时间延长到请求指定的时间,否则请求会被忽略。
这种乐观锁的方式可以保证即使在某些情况下请求被重复执行,也不会对锁的状态产生影响,因为每次请求都会经过Redis服务器的校验。同时,由于Redis采用单线程模型处理请求,所以在执行续期命令时,不会出现并发问题。
Redisson通过Redis提供的乐观锁机制,保证了锁续期的幂等性。
redis主从切换会造成数据丢失,极端情况下
红锁可以解决
红锁有什么问题?
Redis红锁是一种分布式锁实现方式,它通过在多个Redis实例之间协调来确保同一时间只有一个客户端可以持有锁。
尽管Redis红锁被广泛使用,但它并不是没有问题。以下是一些可能出现的问题:
-
网络延迟:由于Redis红锁需要协调多个Redis节点,因此网络延迟会影响锁的性能和可靠性。如果一个节点的响应时间较慢,它可能会影响整个锁的获取和释放速度。
-
时间同步问题:Redis红锁依赖于多个Redis实例的时间同步,即它们的系统时钟必须相同。如果某些Redis实例的时间不同步,则可能导致死锁或竞争情况。
-
误判问题:虽然Redis红锁的设计旨在避免误判,但在极端情况下,两个客户端可能同时获得了锁,这可能会导致数据的不一致性。(当一个挂了,a获取锁,马上重启了,B也会有可能获得锁)
-
可用性问题:如果红锁控制的业务过于庞大,单一 Redis 的可用性难以满足要求。 在高并发场景下,指定的 Redis 集群容量(CPU、IO)也需承受相应的压力。
总之,虽然Redis红锁是一个流行的分布式锁实现方式,但它并不是解决所有分布式锁问题的银弹。在使用时需要针对具体应用场景评估其可靠性和性能。
如何做更细的粒度锁?
我们可以将业务分段加锁,支持并发
加多把锁,越往下锁粒度越细
提交增加幂等和重复校验
redis是如何持久化的?
Redis有两种持久化方式:RDB(Redis Database)和AOF(Append Only File)。
-
RDB持久化:RDB是一种快照式持久化方式,会将Redis在内存中的数据以快照的形式保存到磁盘上。具体实现是将当前数据集以及对应的键值对信息写入一个RDB文件中。RDB持久化是一种比较高效的持久化方式,适合于大规模数据的备份,还支持压缩功能,可以节省硬盘空间。但是,由于数据只会在指定时间间隔之后才会被写入磁盘,因此在出现宕机等异常情况时可能会造成数据的丢失。
-
AOF持久化:AOF是一种日志式持久化方式,AOF持久化会将Redis执行的每个写命令都记录下来,并以指定的格式追加到AOF文件的末尾。这样即使出现异常情况,也能通过重放AOF文件中的日志来恢复数据。相对于RDB持久化,AOF持久化数据更为可靠,但同时也会导致写操作时的性能损失,以及占用更多的磁盘空间。
可以根据需要选择RDB或AOF中的一种或两种持久化方式。通常情况下,建议同时使用RDB和AOF两种持久化方式以获得更好的数据保障。
redis持久化是同步的还是异步的?
Redis持久化是可以异步执行的,但也可以同步执行。
在RDB持久化模式下,Redis默认是异步执行持久化操作。当触发指定条件时,Redis会将数据写入到磁盘中,并且不会阻塞正在进行的其他操作。异步执行持久化操作可以最大程度上保证Redis的性能,但是也可能会导致数据丢失的情况。
在AOF持久化模式下,Redis默认是同步执行持久化操作。每次执行写操作时,Redis都会将对应的命令追加到AOF文件中,并通过fsync或者fdatasync将AOF文件写入磁盘。这种方式相对于异步执行,能够更好地保障数据的可靠性。
但是,在高并发情况下,同步执行持久化操作可能会对Redis的性能产生一定的影响。因此,Redis也提供了一些配置选项,比如可以通过设置aof-rewrite-incremental-fsync选项来减少磁盘写入的次数,从而提高性能。