随笔分类 - Redis
摘要:使用redis的原因,缓存穿透和缓存雪崩 为什么使用redis而不使用map? map是本地缓存,随着jvm关闭而销毁,多实例时每个实例都要保存一份缓存。而redis是分布式缓存,多实例下只保存一份缓存,且提供持久化,即使服务器宕机数据也不会消失。 缓存穿透 访问大量没有做缓存的数据,导致大量请求落
阅读全文
摘要:redis的其它模块:队列、位图、HyperLogLog、布隆过滤器、GeoHash 延时队列 实现队列的一种简单的方式:用zset,其中的score就是剩余时间。 还有一种实现简单队列的方式就是用redis中的list,可以用阻塞读命令blpop、brpop,这样在读不到数据时就会立即进入休眠状态
阅读全文
摘要:Jedis、redis安全、Lua脚本、其他命令 Jedis的使用 基本用法:首先new一个jedispool,然后getResource取到jedis即可,最后jedis要关闭连接。 为了防止发生异常导致jedis没有关闭引发的连接池内连接数不够,要把close语句放在finally块里或者用tr
阅读全文
摘要:订阅与发布:redis的PubSub 订阅: subscribe 具体频道 发布: publish 频道 内容 可以将具体内容发送到对应频道,同时订阅该频道的所有客户端都能接收到该消息。 订阅多个: subscribe 具体频道* 可以订阅具体名称开头的多个频道,即使后续增加了某个新的频道只要在这个
阅读全文
摘要:事务和乐观锁watch redis使用multi开启事务,exec来执行,discard来回滚 事务中的指令会缓存在服务器中的一个事务队列中,服务器一旦受到exec指令就会顺序的执行所有指令并返回所有的运行结果,这些指令在运行时不会相互影响,因为redis是单线程的。 redis的事务并不是原子性的
阅读全文
摘要:客户端与服务器端的通信与redis管道 服务器的任务调度 IO模型采用的是多路复用IO。 redis会为每个客户端套接字都分配一个指令队列,redis会从指令队列中取出指令执行,还会为每个客户端套接字分配一个相应队列,将指令的结果返回给客户端。 redis处理定时任务时会将定时任务放入一个堆中,堆顶
阅读全文
摘要:keys、scan、bigkeys、查看key的存储方式 keys keys 正则表达式 来找到所有符合要求的key,但是这个指令有几个缺点,首先就是没有限制参数,可能查出超多的数据,还有就是它是遍历算法,复杂度是ON,因为redis是单线程,如果数据多的话会导致redis卡顿。 所以代替keys
阅读全文
摘要:限流 一个通用的限流接口就是一个用户只能在特定的时期内对于特定的行为只允许发生有限次。 可以简单的用redis的zset来实现这个功能,zset中的score就代表时间,用户每发起一次请求都维护一次zset,清理掉多余的任务,这里的value只需要保证唯一即可,所以选用毫秒时间戳。但是这个简单的限流
阅读全文
摘要:分布式锁 多个系统要对一个key进行操作,最后操作key的顺序和预期的顺序不一致,此时就用分布式锁对一个目标加锁,使其他进程无法争到已经被占用的锁。 基本指令 加锁指令:setnx key value 移除锁指令:del key 但是如果在加锁后执行出现异常终止导致没有移除锁,就会导致死锁,所以要给
阅读全文
摘要:集群 节点 启动集群 一个集群由多个节点组成,在刚开始的时候各个节点都是相互独立的,我们先以集群模式开启客户端: redis-cli -c -h <host> -p <port> 然后执行下列命令就可以查看集群中的所有节点: cluster nodes 可以看到目前集群只包含自己一个节点,在连接构建
阅读全文
摘要:两种redis集群解决方案:codis和cluster 1、Codis codis是一个代理中间件,当客户端向codis发送指令时,codis负责将指令转发到后面的redis来执行,并将结果返回给客户端。 一个codis实例可以连接多个redis实例,也可以启动多个codis实例来支撑,每个codi
阅读全文
摘要:Sentinel sentinel是redis高可用性的解决方案,一个或多个sentinel实例组成sentinel系统,它可以监视任意多个主服务器以及这些主服务器下的从服务器,当被监视的主服务器进入下线状态时(下线时长超过上限时),自动将下线服务器属下的某个从服务器升级为新的主服务器,如果原来下线
阅读全文
摘要:复制 假设现在有两个redis服务器,地址分别为127.0.0.1:6379和127.0.0.1:12345,如果我们向服务器127.0.0.1:12345发送以下命令: slaveof 127.0.0.1 6379 那么前者就是后者的主服务器,后者是前者的从服务器。进行复制中的主从服务器双方的数据
阅读全文
摘要:服务器 命令的完整执行过程 以set key value为例,说明命令的完整执行过程。 发送命令请求 当用户在客户端中键入一个命令请求时,客户端会将这个命令请求转换成协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器: 读取命令请求 连接套接字会因为客户端的写入而变得可读,服务
阅读全文
摘要:客户端 对于每个与服务器进行连接的客户端,服务器都为这些客户端建立了相应的redisClient结构,这个结构代表客户端状态,redis服务器状态结构的clients属性记录了所有与服务器连接的客户端的状态结构,它是一个链表,如一个服务器与三个客户端连接: 客户端状态包含的属性可以分为两类:一类是比
阅读全文
摘要:事件 redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:文件事件和时间事件。 文件事件是服务器对套接字操作的抽象,是服务器和客户端通信产生的操作;时间事件是服务器需要在给定的时间点执行的操作。 文件事件 文件事件处理器有四个组成部分,分别是套接字、I/O多路复用程序、文件事件分派器以及
阅读全文
摘要:RDB持久化 redis中的内容可以通过RDB持久化保存在磁盘中,RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成该文件对应的redis数据库。RDB持久化可以通过命令手动执行,也可以根据配置定期执行。 RDB文件的创建与载入 save命令和bgsave命令都可以生成RDB文件,前者会造
阅读全文
摘要:服务器中的数据库 redis的数据都保存在服务器的redisServer结构中,它其中有一个redisDb类型的属性*db,它保存着服务器中所有的数据库,初始化服务器时,程序会根据redisServer结构中的int类型属性dbnum来决定创建多少个数据库,它的默认值是16,所以db会指向一个大小为
阅读全文
摘要:对象 redis中所有数据都是以对象的形式存在的,而不是直接使用之前提到过的各种数据结构,使用对象的好处主要有几点: 1、可以很方便的判断对象的类型,进而判断是否可以执行给定的命令。 2、一个类型可以使用不同的底层结构,切换起来很灵活,优化对象在不同场景下的使用效率。 3、基于对象系统,引入了内存回
阅读全文
摘要:底层:基数树radix tree 它是一个有序字典树,支持快速定位、插入和删除。它和trie树很类似,如果某个节点只有一个子节点那么可以采用压缩形式,路径代表一个字符串。 在redis中,它被用来存储stream消息队列,消息队列中的每一个消息ID都是时间戳加序号,有了基数树就能根据ID快速定位到具
阅读全文