
Redis
梦江河
聊聊高并发,数据库,存储
展开
-
Redis分布式锁架构设计
仅当一个key不存在时,才设置成功,返回1,否则设置失败,返回0设置过期时间,redis2.8以前需要通过lua脚本保证setnx命令和expire命令的原子性,2.8以后可以直接通过setnx ex|px命令可能获取锁成功的线程执行业务比较久,比如只锁了3s,但是业务执行了4s,解决方案有两种,第一:评估加锁代码块执行时间,设置锁的时间;第二:watchdog思想,异步线程定期给锁续约;通过del命令实现,但是需要判断锁是否是自己设置的,其实这个是有必要的,因为redis本身的问题,比如设置key成功了,原创 2022-06-12 22:21:44 · 190 阅读 · 0 评论 -
Redis RDB持久化原理
RDB触发方式1)save2)bgsave3)后台触发,配置文件2和3都是通过fork子进程来处理fork本身是系统调用,会阻塞父进程,主要是复制页表耗时,理论上内存越大,越耗时;如果子进程生成rdb过程中,父进程大量修改或者删除key,因为fork是写时复制的原因,会导致父进程必须申请新的内存页,然后拷贝数据到新的内存页进行修改,会产生大量的缺页中断异常...原创 2022-06-12 19:04:16 · 99 阅读 · 0 评论 -
Redis怎么实现分布式锁
怎么实现1)setnx如果一个key已经存在,设置失败,返回0;2)防止死锁设置过期时间 :lua脚本/redis2.8以后的ex命令3)过期时间设置多久如果锁住的代码还没执行完,锁已经过期了,那么其他线程又能获取锁,所以可以开启一个异步线程,如果当前线程还没释放锁,继续延长锁的过期时间;同时释放锁的时候判断key对应的value是不是自己设置的,如果是才删除,用lua脚本保证原子性;绝对安全吗redis实现的分布式锁无论如何也不能保证安全,假设现在是单机redis实现分布式锁,一个线程获取原创 2022-05-05 23:39:00 · 806 阅读 · 0 评论 -
Redis AOF原理
认识1)不是执行写命令后就会写日志到aof文件,而是先写到aof_buf缓冲区,而aof_buf也并非aof文件内核缓冲区。追加是写到aof_buf缓冲区,写入是写入到aof文件内核缓冲区,同步是将aof文件缓冲区的内容同步回磁盘;2)appendfsync配置为always也还是回丢数据,但是也只是丢失一个事件循环的写命令;3)从2可知,就算appendfsync配置为always,基于redis实现的分布式锁也还是会不安全;4)写入到aof文件的内容是resp协议的字符串;5)appendf.原创 2022-04-25 23:33:31 · 1259 阅读 · 1 评论 -
Redis实现微博热度前100
假设微博热度排行榜是根据点赞数量排名怎么实现?可以用Redis的有序集合实现,外层key是固定前缀+排行榜名称,内层value是微博ID,对应的score是点赞数量。每次点赞可以用zincrby key increment score命令给每条微博增加对应的点赞数量。大key问题微博数量很多,如果都放在一个key,那就会产生大key问题。可以把一个key拆分成多个key,比如100个key,每个key只存储一部分微博。然后用一个汇总的key保存排名前N的数据1)这100个key还是保存在一个Re原创 2022-04-24 21:31:10 · 3523 阅读 · 0 评论 -
Redis有序集合zset原理及应用
zset主要功能1)根据value查询对应score;2)根据score来排序;3)指定score的范围,查询对应的value列表;怎么实现1通过hashtable实现,类似Java的HashMap;2和3通过跳表实现;zset是一个混合的数据结构,哈希表+跳表;score相同怎么办按照value的字典序排序跳表可以允许重复key吗跳表是一个有序表,也可以实现不允许key重复的map。比如像下面:("zs",2) -> ("gh",4) -> (“fv”,5)->原创 2022-04-23 11:51:04 · 1216 阅读 · 0 评论 -
Redis事务实现乐观锁原理
事务实现1)multi命令前通过watch命令监听key;2)执行multi命令;3)命令列表;4)exec命令提交事务/discard命令回滚;watch的实现原理1)redis维护着一个全局的watch_keys,也是一个<key,value>结构,key是key+“&&”+连接id,代表是那个客户端连接要监听这个key,value是key的版本号,每次修改这个key,版本号会递增。2)当执行exec命令的时候,会执行事务队列里的每一条命令,执行写命令的时候,会原创 2022-04-21 18:22:30 · 1156 阅读 · 0 评论 -
Redis--为什么字符串emstr的字符串长度是44字节上限?
redis对象的结构一个这样的结构体占用16字节string对象的结构体1)string编码第一种–64位有符号整数2)string编码第二种–embstr3)string编码第三种–raw这种结构需要内存分配两次,一次分配16字节的redis对象结构体,一次分配sds对象,sds是动态扩容的,策略是:字符串在长度小于 1M 之前,扩容空间采用加倍策略,也就是保留 100% 的冗余空间。当长度超过 1M 之后,为了避免加倍后的冗余空间过大而导致浪费,每次扩容只会多分配 1M 大小的原创 2022-04-10 16:14:43 · 1116 阅读 · 0 评论 -
Java实现Redis的有序集合
Redis的有序集合数据结构1)压缩列表2)字典+跳表字典存储value->score的映射,跳表存储score->value的映射,跳表中key是score,那value可能会有多个,怎么排序?Redis默认是根据value的字典序排序引入跳表的原因是Redis要实现根据score的范围查询所有value1)插入过程1、先查询字典,如果value已经存在,保存旧score,更新score2、如果score没有变化,直接返回,否则操作跳表3、根据旧score查询跳表,删除指定的v原创 2021-04-11 14:12:25 · 910 阅读 · 0 评论 -
Redis在业务中的应用-统计日活
统计日活功能1)同一个用户不能统计多次;2)数量不要求十分精确;实现方案1)HyperLogLog(计数不十分精确)pfaddpfcountpfmerge2)位图(计数精确)根据当前系统用户数量创建合适大小的位图,用户id与位图索引做好映射关系,0代表没有操作,1代表已操作,本身已经实现了幂等getbitsetbitbitcount...原创 2021-04-10 09:25:46 · 162 阅读 · 0 评论 -
限流算法-Redis实现滑动窗口限流算法
public class SimpleRateLimiter { private Jedis jedis; public SimpleRateLimiter(Jedis jedis) { this.jedis = jedis; } public boolean isActionAllowed(String userId, String actionKey, int period, int maxCount) { String key = u原创 2021-03-21 08:36:25 · 815 阅读 · 0 评论 -
Redis怎么优雅删除key
拒绝bigkey(防止网卡流量、慢查询)在Redis中,一个字符串最大512MB,一个二级数据结构(例如hash、list、set、zset)可以存储大约40亿个(2^32-1)个元素,但实际中如果下面两种情况,我就会认为它是bigkey。字符串类型:它的big体现在单个value值很大,一般认为超过10KB就是bigkey。非字符串类型:哈希、列表、集合、有序集合,它们的big体现在元素个数太多。一般来说,string类型控制在10KB以内,hash、list、set、zset元素个数不要超过50原创 2021-03-17 23:54:24 · 978 阅读 · 2 评论 -
Redis内存淘汰策略与过期key处理策略
Redis对于过期键有三种清除策略:1. 被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key2. 主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期主动淘汰一批已过期的key3. 当前已用内存超过maxmemory限定时,触发主动清理策略主动清理策略在Redis 4.0 之前一共实现了 6 种内存淘汰策略,在 4.0 之后,又增加了 2 种策略,总共8种:a) 针对设置了过期时间的key做处理:1. volatile-ttl:在筛选原创 2021-03-17 23:45:14 · 199 阅读 · 0 评论 -
Redis杂谈
Redis持久化redis持久化有两种,快照和日志,快照也就是RDB,原理是根据用户配置的信息fork一个子进程对内存数据写到rdb文件,Linux的fork系统调用是读写分离的,具有时刻性,当fork系统调用的时候,内存就会形成一个快照,后续父进程对内存进行修改操作会对相应内存复制一份出来单独进行修改,不会影响子进程,读操作的内存和子进程的相同,快照RDB也可以通过save命令和bgsave命令来执行,bgsave是异步执行,不会阻塞客户端日志AOF是redis每操作一条写的命令就把这条命令写到原创 2021-03-02 10:55:30 · 104 阅读 · 0 评论 -
Redis杂碎知识
Redis哨兵机制选举使用Raft算法JedisCluster原理是cluster nodes获取slot与节点的映射关系,也可以不用这样,直接使用RedisCluster的MOVED原创 2020-10-16 15:35:47 · 101 阅读 · 0 评论 -
Redis集群-ShardedJedis
Redis3.0开始官方支持集群方案,之前的集群方案有codisTwemproxyJedis的ShardedJedis实现key分片介绍原创 2020-10-12 16:36:39 · 278 阅读 · 0 评论 -
Redis-对象
Redis并没有使用简单动态字符串SDS、双端链表、字典、压缩列表、整数集合等数据结构实现键值对数据库,而是基于这些数据结构创建一个对象系统,包括字符串对象、列表对象、哈希对象、集合对象和有序集合对象。Redis在执行命令之前可以根据对象的类型来判断一个对象是否可以执行给定的命令。也可以针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。Redis的对象系统实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象所占用的内存会被自动释放。Red.原创 2020-10-09 10:48:26 · 95 阅读 · 0 评论 -
Redis吊打面试官系列-数据结构-5大对象对应数据结构
字符串整数值embstr编码的简单动态字符串简单动态字符串列表压缩列表双向链表哈希压缩列表字典集合整数集合字典有序集合压缩列表跳跃表和字典原创 2020-09-28 20:38:54 · 138 阅读 · 1 评论 -
Redis吊打面试官系列-数据结构-原理-list
前言:本文是Redis吊打面试官系列的数据结构原理专题,介绍列表list的底层实现前提认识:Redis的list底层是双向链表1、链表节点结构2、list结构3、总体结构总结:链表被广泛用于实现Redis的各种功能,比如列表键、发布订阅、慢查询、监视器等。通过为链表设置不太的类型特定函数,Redis的链表可以用于保存各种不太类型的值...原创 2020-09-28 11:32:16 · 144 阅读 · 0 评论 -
Redis持久化-AOF文件重写
1、客户端输入BGREWRITEAOF命令,Redis会创建一个子进程进行AOF文件的重写,并创建AOF重写缓冲区,这样子进程重写AOF文件,父进程可以继续接受客户端的命令请求,当子进程重写AOF文件完毕后,会通知父进程讲AOF重写缓冲区的内容追加到到重写之后的AOF文件中,追加过程是阻塞的,不接受客户端的命令请求。2、子进程重写AOF文件期间,父进程忽略客户端的BGREWRITEAOF命令,所有客户端的写操作会正常进行,写操作会被记录到AOF缓冲区和AOF重写缓冲区。3、每次事件循环后,AOF缓冲区的原创 2020-09-26 17:04:08 · 1021 阅读 · 0 评论 -
Redis面试知识汇总
Redis面试题为什么Redis很快?采用非阻塞的IO多路复用,使得单个线程可以处理多个连接,并且把相关请求直接直接压到队列中纯内存操作:文件事件分派器从队列中取出事件分配给对应处理器进行处理(连接应答、命令请求、命令回复三中处理器)单线程避免的线程上下文切换的消耗、加锁、解锁等消耗并发竞争问题key过期策略以及内存淘汰机制key过期策略过期集合定时删除(集中处理)原理:贪心策略,默认会每秒进行十次过期扫描默认不会超过 25ms问题:大量key同一时间过期,造成客户端原创 2020-08-03 10:03:55 · 184 阅读 · 5 评论