Redis
文章平均质量分 81
分析Redis的使用,及源码解析
Java识堂
这个作者很懒,什么都没留下…
展开
-
面试官:如何保证缓存和数据库的一致性?
针对这种不一致的情况,我们可以对更新数据库和缓存的操作加一个分布式锁,这样就能保证数据的一致性。基于内存缓存利用率的角度,我们一般不会采用同步更新的操作,因为有可能更新完的缓存并不一定会马上读取,导致缓存中缓存了大量无用的数据,降低缓存命中率。为了保证缓存和数据库的实时一致,我们不能用定时任务来更新缓存,我们要同时更新数据库和缓存,对应的方案有如下两种。从上图看,还是会存在数据不一致的情况,但是在实际中这个问题出现的概率并不高,因为要满足如下3个条件。除了并发的情况,我们还需要考虑异常的情况。原创 2024-03-09 21:46:55 · 148 阅读 · 0 评论 -
Redis源码解析:Redis真的是单线程吗?
介绍参考博客原创 2022-02-02 22:37:08 · 862 阅读 · 0 评论 -
Redis源码解析:详解Redis超实用工具类库Redisson
Redisson工具类库最后推荐一个基于Redis开发的工具类库,这个类库提供了很多实用的功能,比如限流,布隆过滤器,分布式锁等!<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.16.8</version></dependency>我们今天就只分析一下分布式锁.原创 2022-03-06 12:09:00 · 839 阅读 · 0 评论 -
Redis源码解析:如何实现分布式锁?
前言对分布式锁不太了解的小伙伴,可以先看一下这篇文章https://mp.weixin.qq.com/s/8fdBKAyHZrfHmSajXT_dnARedis分布式锁加锁最开始的分布式锁是使用setnx+expire命令来实现的。setnx设置成功返回1,表示获取到锁,返回0,表示没有获取到锁,同时为了避免显示释放锁失败,导致资源永远也不释放,获取到锁后还会用expire命令设置锁超时的时间。但有个问题就是setnx+expire不是原子性的,有可能获取到锁后,还没执行expire命令,也没执.原创 2022-03-01 20:01:34 · 584 阅读 · 0 评论 -
Redis源码解析:IO多路复用,select poll epoll有哪些区别?
基本编程模型listenSocket = socket(); //调用socket系统调用创建一个主动套接字bind(listenSocket); //绑定地址和端口listen(listenSocket); //将默认的主动套接字转换为服务器使用的被动套接字,也就是监听套接字while (1) { //循环监听是否有客户端连接请求到来 connSocket = accept(listenSocket); //接受客户端连接 recv(connsocket); //从客户端读取数据,.原创 2022-02-24 16:32:12 · 1147 阅读 · 0 评论 -
Redis源码解析:Redis有哪些慢操作?
Redis有哪些慢操作?Redis的各种命令是在一个线程中依次执行的,如果一个命令在Redis中执行的时间过长,就会影响整体的性能,因为后面的请求要等到前面的请求被处理完才能被处理,这些耗时的操作有如下几个部分Redis可以通过日志记录那些耗时长的命令,使用如下配置即可# 命令执行耗时超过 5 毫秒,记录慢日志CONFIG SET slowlog-log-slower-than 5000# 只保留最近 500 条慢日志CONFIG SET slowlog-max-len 500执行如下命.原创 2022-02-22 17:39:29 · 1435 阅读 · 3 评论 -
Redis源码解析:如何调试Redis 5.0 源码
添加配置文件下载redis源码,切换到5.0.0分支根目录redis/CMakeLists.txtcmake_minimum_required(VERSION 3.0 FATAL_ERROR)project(redis VERSION 4.0)set(CMAKE_BUILD_TYPE "Debug")get_filename_component(REDIS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)add_subdirectory(deps).原创 2022-01-26 14:41:27 · 1103 阅读 · 0 评论 -
Redis源码解析:Redis主从,哨兵集群搭建
安装CenOs6.9安装Redis4.0.6wget http://download.redis.io/releases/redis-4.0.6.tar.gztar -xvf redis-4.0.6.tar.gzcd redis-4.0.6make启动Redis服务有2种方式(1.使用的是默认配置)cd src./redis-server2.使用指定配置文件启动./redis-server ../redis.conf后台启动修改redis.conf将daemonize后面的值.原创 2018-01-07 16:11:01 · 761 阅读 · 0 评论 -
Redis源码解析:数据结构详解-sds
介绍我们知道Redis是一个键值对数据库,当你执行如下命令时set testKey testValue;rpush fruits banana apple;其中的键就是用sds(Simple Dynamic String,简单动态字符串)来实现的,redis中string类的值也是用SDS实现的(如上面的testValue)。我们来看一下SDS的底层数据结构是啥?3.0版本及以前struct sdshdr { // buf数组中已使用字符的数量 unsigned int len;.原创 2021-01-16 15:13:48 · 1057 阅读 · 0 评论 -
Redis源码解析:数据结构详解-skiplist
跳表是个什么数据结构?本文的很多内容参考自如下文章《Redis 为什么用跳表而不用平衡树?》,为了加深理解,所以用自己的话复述一遍。如图所示,redis中的zset在元素少的时候用ziplist来实现,元素多的时候用zskiplist来实现。那么skiplist是一个什么样的数据结构呢?skiplist(跳表)是一种为了加速查找而设计的一种数据结构。它是在有序链表的基础上发展起来的。如下图是一个有序链表(最左侧的灰色节点为一个空的头节点),当我们要插入某个元素的时候,需要从头开始遍历直到找到该元.原创 2021-01-30 20:53:35 · 1816 阅读 · 3 评论 -
Redis源码解析:数据结构详解-quicklist
介绍在redis 3.0版本及以前,采用压缩链表(ziplist)以及双向链表(linkedlist)作为list的底层实现。当元素少时用ziplist,当元素多时用linkedlist在redis 3.0版本以后,采用quicklist作为list的底层实现quicklist是一个双向链表,链表中每个节点是一个ziplist假如说一个quicklist包含4个quickListNode,每个节点的ziplist包含3个元素,则这里list中存的值为12个。quicklist为什么要这样设计.原创 2021-01-24 23:49:01 · 1367 阅读 · 0 评论 -
Redis源码解析:数据结构详解-intset
介绍intset是Redis中set的底层数据结构,当集合中全为整数,并且元素数据不多时,会用intset来实现set,inset和ziplist一样,都是一块连续的存储空间typedef struct intset { // 编码方式 uint32_t encoding; // 元素数量 uint32_t length; // 保存元素的数组 int8_t contents[];} intset;contents:contents数组是整数集合的底层.原创 2021-01-27 23:26:46 · 859 阅读 · 0 评论 -
Redis源码解析:Redis Cluster
介绍ASK和MOVED的区别MOVED代表槽的负责权已经从一个节点转移到另一个节点,客户端收到槽i的MOVED错误后后续每次遇到槽i的命令请求时,都可以直接将命令发送至MOVED指向的节点ASK只是2个节点在迁移槽的过程中使用的一种临时错误,客户端收到槽i的ASK错误后只会在下一次请求中将命令发往ASK指向的节点,对后续不会产生任何影响参考博客...原创 2022-02-12 19:41:08 · 640 阅读 · 0 评论 -
Redis源码解析:Redis事务能保证ACID吗?
介绍Redis事务中有命令语法错误时,无法保证原子性,其他情况可以保证原子性Redis可以保证一致性,隔离性,无法保证原子性能和持久性参考博客[1]原创 2022-02-11 11:25:42 · 680 阅读 · 0 评论 -
Redis源码解析:Redis哨兵机制
RDB文件结构参考博客原创 2022-02-05 22:06:07 · 994 阅读 · 0 评论 -
Redis源码解析:事件驱动框架
介绍为了高效的处理网络请求,演化出了Reactor模型。Reactor模型主要有reactor,acceptor,handler三种角色reactor:分配事件acceptor:建立连接handler:处理请求单Reactor单线程accept->read->处理业务逻辑->write 在一个线程单Reactor多线程accept,read,write复用一个线程处理请求用一个工作线程池主从Reactor多线程accpet复用一个线程read write复用原创 2022-02-02 21:21:23 · 3931 阅读 · 1 评论 -
Redis源码解析:一个命令的执行过程
通信协议Redis客户端和服务端之间使用一种名为RESP(REdis Serialization Protocol)的协议进行通信。RESP设计的十分精巧,下面是一张完备的协议描述图:各种命令执行server.c参考博客协议[1]https://www.jianshu.com/p/f670dfc9409b[2]https://zhuanlan.zhihu.com/p/345327284...原创 2022-02-02 20:44:57 · 909 阅读 · 0 评论 -
Redis源码解析:keys不让用,scan小心坑
介绍SCAN 命令用于迭代当前数据库中的数据库键。SSCAN 命令用于迭代集合键中的元素。HSCAN 命令用于迭代哈希键中的键值对。ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。intset和ziplist会返回所有的数据参考博客命令实现[1]https://www.jianshu.com/p/be15dc89a3e8scan详解[2]http://redisdoc.com/database/scan.html#scan...原创 2022-01-27 19:56:03 · 2243 阅读 · 0 评论 -
Redis源码解析:Redis数据结构为什么既省内存又高效?
协议参考博客协议[1]https://www.jianshu.com/p/f670dfc9409b[2]https://zhuanlan.zhihu.com/p/345327284原创 2022-01-26 15:36:30 · 1100 阅读 · 0 评论 -
Redis源码解析:单线程的Redis为什么能支持10w+的QPS?
单线程为什么能支持10w+的QPS?我们经常听到Redis是一个单线程程序。准确的说Redis是一个多线程程序,只不过请求处理的部分是用一个线程来实现的。Redis是如何用单线程来实现每秒10w+的QPS的呢?使用IO多路复用非CPU密集型任务纯内存操作只用一个线程怎么来处理多个客户端的连接呢?这就不得不提IO多路复用技术,即Java中的NIO。当我们使用阻塞IO(Java中的BIO),调用read函数,传入参数n,表示读取n个字节后线程才会返回,不然就一直阻塞。write方法一般不会.原创 2021-02-04 22:23:38 · 2572 阅读 · 0 评论 -
Redis源码解析:缓存淘汰策略
介绍Redis是一个内存数据库,当Redis使用的内存超过物理内存的限制后,内存数据会和磁盘产生频繁的交换,交换会导致Redis性能急剧下降。所以在生产环境中我们通过配置参数maxmemoey来限制使用的内存大小。当实际使用的内存超过maxmemoey后,Redis提供了如下几种可选策略。noeviction:写请求返回错误volatile-lru:使用lru算法删除设置了过期时间的键值对volatile-lfu:使用lfu算法删除设置了过期时间的键值对volatile-random:在设置.原创 2021-01-24 12:47:39 · 12723 阅读 · 17 评论 -
Redis源码解析:dict与迭代器
介绍在之前的文章中我们提到,Redis中的数据是放在一个字典中的。例如当我们执行如下命令后,redis的字典结构如下set bookName redis;rpush fruits banana apple;Redis中hash也用dict来实现的,zset中存储value和score值的映射关系也是用dict来实现的。其实Reids中dict的实现和Java中HashMap的实现很类似,也是采用数组+链表的形式实现的。结构如下typedef struct dict { // 类型特定.原创 2021-01-16 18:32:08 · 1402 阅读 · 1 评论 -
Redis源码解析:Redis持久化策略详解(一)
介绍Redis中的数据存在内存中,如果突然宕机,那么内存中的数据将全部丢失。如果数据能从后端数据库恢复还好,如果数据只存在Redis中,那数据就全丢失了。并且如果请求量很多,MySQL服务器的压力会很大。所以最好的方式是对数据进行持久化,并能当宕机的时候能快速恢复在Redis中有如下两种持久化方式,rdb快照和aof日志RDBrdb就是对当前数据库的状态做一个快照,将某个阶段的数据通过二进制文件保存下来。你可以类比照相。内存中的数据越多,生成快照的时候就越长,同时将快照写入磁盘耗费的时间也越长。.原创 2021-01-10 15:48:49 · 1877 阅读 · 0 评论 -
Redis源码解析:Redis持久化策略详解(二)
开启aofredis.conf# 是否开启 aofappendonly yes# aof 文件名appendfilename "appendonly.aof"# aof文件持久化策略,可选值为always,everysec,noappendfsync everysec# 是否开启 aof 文件重写no-appendfsync-on-rewrite no# aof 重写策略auto-aof-rewrite-percentage 100auto-aof-rewrite-min-s原创 2022-01-26 18:08:45 · 856 阅读 · 0 评论 -
Redis源码解析:数据结构详解-ziplist
压缩列表的数据结构zset和hash容器对象在元素个数较少的时候,采用压缩列表(ziplist)来存储。压缩列表是一块连续的内存空间。结构如下属性类型长度用途zlbytesuint32_t4字节整个压缩列表占用字节数zltailuint32_t4字节最后一个元素距离压缩列表起始位置的偏移量,用于快速定位最后一个元素zllenuint16_t2字节压缩列表的节点数量,值小于UINT16_MAX(65535)时,这个属性值就是压缩列表包含节点的数量,.原创 2021-01-09 20:56:35 · 882 阅读 · 0 评论 -
Redis源码解析:数据明明都过期了,为啥还占着内存?
介绍我们可以给Redis中的key设置过期时间,那么当key过期了,它在什么时候会被删除呢?如果让我们写Redis过期策略,我们会想到如下三种方案定时删除,在设置键的过期时间的同时,创建一个定时器。当键的过期时间来临时,立即执行对键的删除操作惰性删除,每次获取键的时候,判断键是否过期,如果过期的话,就删除该键,如果没有过期,则返回该键定期删除,每隔一段时间,对键进行一次检查,删除里面的过期键定时删除策略对CPU不友好,当过期键比较多的时候,Redis线程用来删除过期键,会影响正常请求的响应.原创 2021-01-09 18:44:46 · 1243 阅读 · 1 评论 -
Redis源码解析:主从复制
介绍在生产环境中,为了系统的可靠性,我们会对Redis搭建主从。这样当一个实例发生宕机,另一个实例中还有数据,还能继续提供服务。主从库之间采用的是读写分离的模式。读操作:主库,从库都可以执行写操作:只能主库上执行,主库将操作同步给从库因为主从库都可以接收读请求,提高了系统的QPS。那么主从库之间如何进行数据同步呢?全量复制我们可以通过replicaof命令或者replicaof设置来让redis形成主从库的关系(redis 5.0之前使用slaveof命令)假设现在有两个实例,实例一(17.原创 2021-01-09 18:38:18 · 978 阅读 · 0 评论