Redis
潘广宇
主攻Golang|Python|PHP|数据库|高并发架构|人工智能,Base广州,博客主要写一些工作上遇到的问题和处理经验
展开
-
PHP 通过 Redis 解决并发请求的操作问题
SETNX(SET if Not eXists)是 Redis 中的一个原子命令,用于设置键-值对,但只有在键不存在时才执行设置操作。可以利用 SETNX 命令来实现并发请求的互斥处理,确保只有一个请求能够成功执行。需要注意的是,即使 SETNX 返回 1,表示当前请求获取到了锁并执行了业务逻辑,仍需要在合适的时机释放锁,以防止死锁情况的发生。如果 SETNX 返回 1,表示当前请求是第一个获取到锁的请求,可以执行相应的业务逻辑;如果 SETNX 返回 0,表示已经有其他请求获取到了锁,当前请求不处理。原创 2023-08-31 10:36:49 · 1042 阅读 · 0 评论 -
Redis 大键值对 Big Key 懒惰删除机制
一、懒惰删除介绍在删除元素数量很多的集合(set/hash/list/sortedSet)时,无论是使用DEL命令删除还是redis为了释放内存空间而进行的删除,在删除这些big key的时候,会导致redis主线程阻塞。在redis 4.0版本中,提供了lazy free(懒惰删除)的特性解决 big key 删除导致的主线程阻塞的问题。使用lazy free删除big key时,和一个O(1)指令的耗时一样,亚毫秒级返回(返回结果不会产生等待阻塞),真正删除key的耗时动作交由后台子线程执行原创 2022-04-25 14:39:33 · 1175 阅读 · 0 评论 -
Redis 过期 key 清理删除策略汇总
Redis 底层使用了三种策略来清理过期的key一、被动清理触发条件:读/写一个已经过期的key当读写一个key时,Redis首先检查key是否存在,若存在且已经过期,则删除key的同时返回nil给客户端二、定期清理触发条件:Redis定期检查redis会定期执行清理过期key的任务,运行频率由redis.conf中的hz参数决定,取值范围1~500,默认是10,代表每秒运行10次。清理过程如下:1)遍历所有的db2)从db中设置了过期时间的key的集合中随机检查20个原创 2022-04-22 15:55:03 · 2766 阅读 · 0 评论 -
Redis 内存占满导致的 Setnx 命令执行失败
一、问题发生正常情况下,通过 setnx 设置的一个锁,应该会1s后过期(防止并发请求,处理相同逻辑),但是实际发生的情况是,第一次处理下面的逻辑,就抛出异常。说明 setnx 函数返回了 false。$redis_key_lock = 'lock'; //@todo 设置了一个1s的锁$lock = $redis->setnx($redis_key_lock, 1);//@todo 锁将会在1s后过期$redis->expire($redis_key原创 2022-04-22 11:39:16 · 2110 阅读 · 0 评论 -
Redis 异常 read error on connection 解决方案
造成原因与场景:在接口连接 redis 时,在 Redis->auth() 中抛出异常:PHP Fatal error: Uncaught exception 'RedisException' with message 'read error on connection'出现原因:通过 pconnect 的 redis 长连接不会主动释放,会一直保持在php-fpm进程中,等待完成下一个请求的任务。这样会出现以下两种情况:1)假如这个连接已经断开了,下个请求可能直接使用上个断..原创 2022-04-20 14:31:07 · 5361 阅读 · 0 评论 -
Redis 批量删除键
删除 a_* 开头的键redis-cli -h 127.0.0.1 -p 6379 keys "a_*" | xargs redis-cli -h 127.0.0.1 -p 6379 del原创 2021-11-23 17:12:28 · 765 阅读 · 0 评论 -
官方系列之 Redis 键空间通知
当 Redis 某些键触发某些操作时,Redis 将操作的相关信息通过 发布/订阅 的方式进行通知,订阅消息不可靠可能会丢失。举例来说,在数据库0的mykey上执行了DEL操作,这时Redis将发布两条通知消息到2个不同的订阅频道PUBLISH __keyspace@0__:mykey delPUBLISH __keyevent@0__:del mykeykeyspace 被叫做键空间通知(上面例子:所有跟mykey空间有关的操作),keyevent 被叫做键事件通知(上面例子:所有跟删除原创 2021-07-28 15:39:30 · 188 阅读 · 0 评论 -
官方系列之 Redis 分布式锁 / RedLock 算法
算法需要具备的三大特性● 安全属性:独享(相互排斥)。在任意一个时刻,只有一个客户端持有锁。● 活性A:无死锁,即便持有锁的客户端崩溃,锁仍然可以被获取。● 活性B:容错,只要大部分Redis节点都活着,客户端就可以获取和释放锁.单节点情况客户端A向服务端请求获取锁:set key_ rand_A NX PX 300000# key_ 代表锁名称,rand_A是A客户端随机生成的密钥,NX代表只有锁不存在的时候,才能获取(设置),PX是锁的自动过期时间(过期锁自动释放机制)原创 2021-07-28 11:43:26 · 240 阅读 · 0 评论 -
官方系列之 Redis 事务
MULTI 开启事务EXEC 执行事务DISCARD 放弃事务WATCH/UNWATCH 事务执行前监听(取消监听)KEY是否被修改事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。Redis 不支持事务回滚如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。如...原创 2021-07-27 14:52:58 · 58 阅读 · 0 评论 -
官方系列之 Redis 过期
● 当 key 超时后,只有当执行改变 key 的值操作时,才会被清除,如 INCR,SET,DEL 等操作● 使用 PERSIST 可以清除超时,变成一个永久的 key● 当 key 被 RENAME 为其他 key,相关的超时时间也会转移到新的 key 上面。● 通常 keys 创建时没有设置相关过期时间,默认是永久,除非使用命令移除,如 DEL 命令。● Keys的过期时间使用Unix时间戳存储● 淘汰过期 key:过期有两种方式:被动和主动方式。主动过期:当一些客户端尝试原创 2021-07-27 10:11:08 · 134 阅读 · 0 评论 -
官方系列之 Redis 内存优化
一、集合可被压缩存放存储集合数据的时候可以采用内存压缩技术,以使用更少的内存存储更多的数据。如 Hashes,Lists,Sets和Sorted Sets,当这些集合中的所有数都小于一个给定的元素,并且集合中元素数量小于某个值时,存储的数据会被以一种非常节省内存的方式进行编码,使用这种编码理论上至少会节省10倍以上内存(平均节省5倍以上内存),使用这种编码是用CPU换内存。在 redis.conf 中可以进行配置:hash-max-ziplist-entries 64hash-max-.原创 2021-07-26 20:14:58 · 271 阅读 · 0 评论 -
官方系列之 Redis Eval 调用 Lua 脚本
一、Eval 函数介绍EVAL 和 EVALSHA 使用内置的 Lua 解释器,可以对 Lua 脚本进行求值。EVAL的第一个参数是一段 Lua 脚本程序。EVAL的第二个参数是参数的个数,后面的参数为 [key1] [key2] ... [value1] [value 2]键名参数可以在 Lua 中通过全局变量 KEYS 数组,用1为基址的形式访问(KEYS[1]、KEYS[2])键值通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似(ARGV[1]、ARGV[2]原创 2021-07-26 17:30:27 · 906 阅读 · 0 评论 -
官方系列之 Redis 发布订阅
Publish [Channel] [message] 发布信息到指定频道SUBSCRIBE [Channel] 订阅频道信息,收到的信息类型是message类型UNSUBSCRIBE [Channel] 取消订阅频道信息PSUBSCRIBE [Channel_pattern] 订阅某个模式的频道信息,如 foo* foo开头的频道,收到的信息类型是pmessage...原创 2021-07-26 16:14:37 · 112 阅读 · 0 评论 -
官方系列之 Redis Pipeline 大幅改善多个命令执行 TTS
什么是TTS:客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。服务端处理命令,并将结果返回给客户端。TTS(Round Trip Time)表示该过程的往返时间当多个命令分多次执行时,如果网络延迟,就会造成TTS总和变大。利用管道技术,将多个命令一次发送给Redis服务端,只需要等待最后一次服务器的答复。shell例子:> (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | redis-cli -a原创 2021-07-26 14:57:45 · 344 阅读 · 0 评论 -
利用 Redis Bitmap 统计用户在线次数
场景:统计用户A在今年以来的上线次数基础知识:setbit 用于设置某个key某个offset下面比特位的值,只能是0或1bitcount 用于统计每个key中,比特位被标记为1的个数如:> setbit a 0 1> setbit a 1 0> setbit a 2 1 // a的值为 101> bitcount areturn > 2例子:> setbit A 0 0> setbit A 1 ...原创 2021-07-26 11:01:00 · 1257 阅读 · 1 评论 -
利用 Lua 脚本在 Redis 中实现秒杀商品减库存
一、情景描述公司开展商品秒杀活动,共有 A、B、C、D 四个商品提供秒杀抢购,每件商品限售 5 件,售完即止。二、实现方案1)使用 redis 保存四件商品的库存数量,如:set goods_A 5set goods_B 5set goods_C 5set goods_D 52)利用 lua 脚本操作库存数量:-- 判断商品是否存在local isExi...原创 2020-04-20 14:24:24 · 1734 阅读 · 0 评论 -
Redis + Logstash 缓存数据导入 Elasticsearch 实战
应用场景:将 redis 队列存放的数据导入 elasticsearch,进行全文搜索一、编写 redis-es.conf ,文件可以存放在:/etc/logstash/conf.d/redis-es.confinput { redis { data_type => "list" # 使用 redis 的list数据类型 ...原创 2020-03-20 16:19:04 · 1560 阅读 · 0 评论 -
Redis 发布与订阅
Redis 的发布订阅比较简单,一个客户端可以同时订阅多个频道,一个频道可以被多个客户端订阅。SUBSCRIBE foo [..other Channel] -- 客户端订阅foo频道 -- 客户端可以一次订阅多个频道UNSUBSCRIBE foo ...原创 2019-03-31 21:09:16 · 370 阅读 · 0 评论 -
Redis LRU 缓存回收机制
一、可通过设置 redis.conf 设置 redis 使用的最大内存maxmemory 100mb -- 设为0表示不限制,64位默认不限制,32位默认限制3GB二、当超过该内存值时,redis 将使用回收机制进行接下来的键的写入maxmemory noeviction1)noeviction : 对写入指令直接返回错误(默认) 2)allkeys-lru : ...原创 2019-03-31 22:07:12 · 736 阅读 · 0 评论 -
Redis 监听过期的 key 事件
Redis从2.8.0版本后,推出 Keyspace Notifications 特性。Keyspace Notifications 此特性允许客户端可以以 订阅/发布(Sub/Pub)模式,接收那些对数据库中的键和值有影响的操作事件。Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 如果程序需要可靠事件通知, 那么目前的键空间通知可能不适合:当订阅事...原创 2019-03-27 19:50:06 · 5127 阅读 · 0 评论 -
Redis 实现搜索关键词自动补全
一、字典型自动补全Redis 的有序集合有一个特性:score 相同时,是按照字典顺序排序的。如我们需要获取带有某个前缀的提示词,将每个关键词的前缀分别提取并存储在有序集合中,如:foobar,则将 (f,fo,foo,foob,fooba ... foobar$) ,最后一个 foobar$ 表示这是该词的结尾,$ 可以标记为词的结尾符127.0.0.1:6379> zran...原创 2019-04-01 14:17:54 · 2495 阅读 · 0 评论 -
Redis HyperLogLog 基数计算
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。因为HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身。一、什么是基数统计...原创 2019-04-01 23:35:14 · 860 阅读 · 0 评论 -
Nginx Lua 开发 - Redis 操作
一、Nginx 支持3种方法访问 Redis1)HttpRedis : 提供指令少,功能单一2)HttpRedis2Module : 比 HttpRedis 操作更灵活,功能更强大3)Lua-resty-redis 库 : Openresty 提供的操作 Redis 的接口库,需要通过 --with-luajit 编译安装二、HttpRedis2Module 适合简单访问 Redi...原创 2019-03-28 17:51:36 · 1243 阅读 · 0 评论 -
简要概述 Redis 与 Memcache 的比较
1)Redis 支持更加丰富的数据存储类型,String、Hash、List、Set 和 Sorted Set。Memcached 仅支持简单的 key-value 结构。2)Memcached key-value存储比 Redis 采用 hash 结构来做 key-value 存储的内存利用率更高。3)Redis 提供了事务的功能,可以保证一系列命令的原子性4)Redis 支持数据的...原创 2019-03-10 10:57:26 · 1427 阅读 · 0 评论