redis
文章平均质量分 77
红丶
Stay hungry, stay foolish.
展开
-
记一次线上JedisConnectionException
前言在前几天的一个springboot 项目中,使用到了redis 作为缓存,理所当然地使用了连接池,因为频繁的创建和销毁连接实在是太耗费资源了,可是在测试环境下使用是没有问题的,将项目放到了线上后就时不时出现连接的异常,具体异常信息如下:ERROR --- [nio-8080-exec-2] c.l.a.exception.GlobalExceptionHandler : error: org.springframework.data.redis.RedisConnectionFailureEx原创 2021-05-03 14:40:40 · 304 阅读 · 0 评论 -
探秘 Redis 跳跃列表
跳跃列表(skiplist)是一种有序的数据结构,它通过在每个节点维护多个指向其他节点的指针,我们可以平均O(logN) 的时间复杂度快速访问节点,大部分情况下它的性能可以和平衡树相媲美,不过实现起来更为简单。跳跃列表是 Redis 中有序集合的一种实现方式,在有序集合的元素数量较多或者是元素成员长度较长时,Redis 就会使用跳跃列表加字典来存储元素。大家都知道 zset 每一个 value 都有一个 score ,zset 根据每个 value 的 score 将其排序,并且元素不会重复,那么,为了原创 2021-02-05 18:46:22 · 134 阅读 · 1 评论 -
探秘 Redis 快速列表
快速列表(quicklist )是列表(list)的底层实现之一,当列表中元素较少,并且里面的字符串的长度不长时,Redis 使用的压缩列表(ziplist)来存储的,这个大家都知道了哈,然而当列表中的元素越来越多,或者某一个元素的长度太大时就会使用快速列表来存储元素了。这里需要说明的一点是 Redis 早期版本存储列表数据结构使用的是压缩列表 ziplist 和普通的双向链表linkedlist,也就是元素少时用 ziplist,元素多时用 linkedlist,但是这种存储结构,每个节点里面光是两个指原创 2021-02-05 17:32:30 · 148 阅读 · 0 评论 -
探秘 Redis 整数集合
整数集合(intset)是集合的底层实现之一,当 set 集合容纳的元素都是整数并且元素个数较小时,Redis 会使用 intset 来存储集合元素。intset 是 Redis 用于保存整数值的集合抽象数据结构,它是一种紧凑的数组结构,并且可以保存类型为 int16_t, int32_t 和 int64_t 的整数值,并且集合中不会出现重复的元素。注意:一旦在集合中加入了字符串,集合就会从 intset 变成 hash 结构。intset 定义typedef struct intset {原创 2021-02-05 16:17:30 · 176 阅读 · 0 评论 -
探秘 Redis 压缩列表
压缩列表,即ziplist,是列表(list),哈希(hash)和有序集合(zset)的底层实现之一,Redis 为了节约内存空间使用,在这些容器对象在元素个数较少的时候,采用压缩列表 (ziplist) 进行存储。list示例:zset示例:hash示例:压缩列表的构成压缩列表是由一系列经过特殊编码的连续的内存空间,元素之间紧挨着存储,没有任何冗余空隙。一个压缩列表可以包含任意的多个节点,每个节点可以保存一个字节数组或者整数值。struct ziplist<T> { int3原创 2021-02-05 15:44:44 · 149 阅读 · 0 评论 -
探秘 Redis 中的字典
字典(dict) 也可称作映射(map),就像 Java 中的 Map ,Python 中的 dict 一样,是一种用于保存键值对(key - value)的抽象数据结构。但是 Redis 所使用的 C 语言并没有内置这种数据结构,所以 Redis 自己实现了字典这个数据结构。字典可以说是 Redis 中出现最为频繁的数据结构了,整个 Redis 数据库就是使用字典来作为底层实现的,Redis 中所有的键值就构成了一个全局的字典,比如我们执行命令:set test_key test_value,就会在这个原创 2021-02-05 12:54:36 · 366 阅读 · 0 评论 -
Redis字符串底层实现
Redis 中最常用的可能就是字符串了吧,我们通过 set 命令可以存储一个键值到缓存中,key 是一个字符串,value 也是一个字符串,可是你知道 Redis 中的这个字符串的底层结构吗?探秘SDS大家的可能都知道 Redis 是基于 C 语言实现的,但是其实 Redis 并没有直接使用 C 语言里面的字符串,即传统的以空字符(\0)结尾的字符数组,而是字节构建了一种名为 SDS (Simple Dynamic String)的简单动态字符串。Redis 中几乎所有用到字符串的地方都是使用的 SD原创 2021-02-04 10:26:46 · 244 阅读 · 0 评论 -
redis企业级持久化方案
企业级的持久化的配置策略redis.conf:save 60 1000:每隔60秒如果有1000个更新则保存一份RDB,如果你希望尽可能确保说,RDB最多丢1分钟的数据,那么尽量就是每隔1分钟都生成一个快照,1000这个数字根据你自己的应用和业务的数据量,你自己去决定AOF一定要打开appendonly yes : 打开AOFappendfsync everysec :每隔一秒将AOF刷到磁盘上auto-aof-rewrite-percentage 100: 当前AOF大小膨胀到超过上次100%原创 2020-12-10 21:27:45 · 207 阅读 · 0 评论 -
Redis 并发竞争解决方案
什么是 redis 的并发竞争?所谓redis 的并发竞争,通俗地说就是多客户端同时并发写一个 key,可能本来应该后修改的数据先修改到了,导致数据的版本错乱,或者是多客户端同时获取一个 key,修改值之后再写回去,只要顺序错了,数据就错了。举一个栗子多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,那么最后的值应该是4,但是实际修改顺序却变成了4,3,2,那么最后的值就变成了2。解决方案方案1可以使用独占锁的方式,类似操作系统的mutex机制。不过独占锁性能消耗较高原创 2020-12-10 21:02:38 · 440 阅读 · 0 评论 -
缓存击穿及其解决方案
缓存击穿是什么?缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发请求的用户特别多(就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况),当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞,引起数据库压力瞬间增大,造成过大压力。解决方式可以将热点数据设置为永远不过期;基于 redis 或者 zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据。原创 2020-12-07 22:17:40 · 1614 阅读 · 0 评论 -
缓存穿透及其解决方案
缓存穿透描述:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时候这个请求就穿透了nginx,redis和mysql,导致每次这种请求都会打入数据库,这时的请求发起者很可能是攻击者,这种大量的不存在的请求会导致数据库压力过大。解决方案:缓存穿透的解决方案,其实非常的简单,就是说每次如果从源服务(商品服务)查询到的数据是空,就说明这个数据根本就不存在,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,原创 2020-12-07 22:09:30 · 568 阅读 · 0 评论 -
缓存雪崩问题及其解决方案
什么是缓存雪崩描述:缓存雪崩一般是指,缓存层(例如redis集群)出现了异常,不能正常工作了。于是所有的请求都会达到存储层(数据库层),存储层的QPS会暴增,出现大量请求压垮存储层的情况。当然如果缓存设置了过期时间,导致大量数据同时过期,进而大量请求打入数据库中,引起数据库压力过大甚至宕机。对于这种情况我们可以将缓存数据的过期时间设置随机或者设置缓存永不过期。然后实际上可能redis集群出现了崩溃,导致缓存不可用,那么此时可能会导致以下问题:缓存服务大量对redis的请求被hang住,占用资源原创 2020-12-07 21:49:48 · 738 阅读 · 0 评论 -
高并发下数据库与缓存双写不一致解决方案
为什么会出现数据库与缓存不一致?缓存作为抵挡前端访问洪峰的工具,用的好的话可以大大减轻服务端压力。我们知道缓存中的数据来源是数据库,如果数据库的数据发生了改变怎么办呢?难道直接去修改缓存吗?最经典的缓存+数据库读写的模式,cache aside pattern为什么是删除缓存,而不是更新缓存呢?原因很简单,在复杂一点的缓存场景,缓存往往不是简单从数据库中直接取出来的值。比如可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的。另外更新缓存原创 2020-12-05 17:20:19 · 442 阅读 · 0 评论 -
Redis 6.0 新特性----多线程来了
5 月 2 日Redis 6.0正式发布了。这个版本提供了诸多新特性及功能改进,比如新网络协议RESP3,新的集群代理,ACL等,本文围绕其中关注度最高的“多线程的引入”来说明。Redis6.0之前的版本真的是单线程吗?Redis在处理客户端的请求时,包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。但如果严格来讲从Redis4.0之后并不是单线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无原创 2020-11-27 13:31:23 · 200 阅读 · 0 评论 -
redis 的持久化方式
问题Redis的数据都缓存在内存中,如果没有配置持久化, redis 宕机了再重启,内存里的数据就全部都弄丢了啊。于是需要开启redis的持久化功能,将数据写入内存的同时,异步的慢慢的将数据写入磁盘文件里,进行持久化。当redis 宕机重启,会自动从磁盘上加载之前持久化的一些数据,也许会丢失少许数据,但是至少不会将所有数据都弄丢。可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(ap原创 2020-11-26 14:47:35 · 91 阅读 · 0 评论 -
redis过期策略和内存淘汰策略
redis 过期策略Redis是key-value类缓存数据库,我们在设置Redis中缓存的key时可以设置过期时间。那么Redis是如何处理过期的key 呢?这就要谈到Redis的过期策略了。过期策略通常有以下三种:定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。优点:可以立即清除过期的数据,保证内存被尽快释放;缺点:会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。惰性删除:只有当访问一个key时,才会判断该key是否已过期,过原创 2020-11-26 14:22:21 · 114 阅读 · 0 评论 -
为什么redis单线程模型能够支持高并发?
为什么redis 的线程模型是单线程?Redis基于Reactor模式开发了自己的网络事件处理器——文件事件处理器 (file event handler),这个文件事件处理器是单线程的,所以 redis 才叫做单线程的模型。文件事件处理器组成部分多个套接字IO 多路复用程序文件事件分派器事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)特点文件事件处理器使用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。被监听的套接字准原创 2020-11-26 14:02:38 · 110 阅读 · 0 评论 -
springboot 自定义RedisCache注解
springboot提供的Cache注解当我们在编写查询数据库Service时,需要现在redis中查询是否有所需数据的缓存,如果有,则无需去查询数据库,这无疑提高了查询速度同时减轻了数据库的压力。在使用springboot整合redis时,相信大家都对@Cacheable这个注解不陌生吧例如我们需要在Service查询数据库前先去缓存中查询,如果没有在查询数据库,有则不去查询,我们只需要在redisTemplate配置类中加入@EnableCaching注解,并配置Spring Cache注解功能,原创 2020-10-03 18:17:22 · 680 阅读 · 0 评论 -
redis 集群
环境信息centos7redis5安装rediswget http://download.redis.io/releases/redis-5.0.3.tar.gztar -zxvf redis-5.0.3.tar.gzcd redis-5.0.3 make# 安装到 /usr/local/redis 目录中 安装的文件只有一个bin目录make install PREFIX=/usr/local/redis/ # 创建配置文件和data存放目录mkdir /usr/local/red原创 2020-10-02 22:23:12 · 246 阅读 · 0 评论 -
redis 哨兵
上一篇文章讲解了redis主从复制,可是当主服务器宕机后,我们需要手动把一台从服务器切换为主服务器,这费事费力,还会造成一段时间内服务不可用。显然我们并不推荐这种方式,更多时候,我们优先考虑哨兵模式。哨兵模式Sentinel哨兵是redis官方提供的高可用方案,可以用它来监控多个Redis服务实例的运行情况。哨兵是一个独立的进程,作为进程,它会独立运行。Redis Sentinel是在多个Sentinel进程环境下互相协作工作的。下面我们将搭建两个哨兵准备二台redis服务复制一份redis,并将原创 2020-10-02 15:49:24 · 232 阅读 · 0 评论 -
redis 主从复制
什么是Redis主从复制?通俗的说就是我们有一台主redis服务器,多台从redis服务器,一般主服务器用于写数据,从服务器只能读数据,从服务器会自动同步主服务器数据。为什么要使用Redis主从复制?读写分离故障切换,当master出问题后还有slave节点可以使用redis-server单点故障单节点QPS有限搭建主从复制我们将redis文件复制两份,修改其中一份的配置文件,将其端口号改为6380port 6380将两个redis服务启动。同时启动两个客户端,客户端指定端口连接原创 2020-10-02 14:07:34 · 98 阅读 · 0 评论 -
redis 缓存过期监听
redis 缓存过期通过 Redis 的订阅与发布功能(pub/sub)来进行分发, 故需要开启 redis 的事件监听与发布修改 redis配置文件修改notify-keyspace-events ""为notify-keyspace-events “Ex”重启redis打开两个客户端,测试配置是否生效客户端1监听过期时间:SUBSCRIBE __keyevent@0__:expired客户端2设置带有过期时间为1秒的key:set ex_key ex_value ex 1 客原创 2020-10-01 22:02:04 · 458 阅读 · 0 评论 -
java redis连接池
NOSQL数据库NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。NOSQL数据库的优缺点优点:原创 2020-07-08 15:42:03 · 3840 阅读 · 0 评论 -
redis 发布订阅模式
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。Redis 客户端可以订阅任意数量的频道。以下实例演示了发布订阅是如何工作的,需要开启两个 redis-cli 客户端:在我们实例中我们创建了订阅频道名为 sms:SUBSCRIBE sms 现在,我们先重新开启个 redis 客户端,然后在同一个频道 sms发布两次消息,订阅者就能接收到消息:PUBLISH sms "hello sms"订阅者的客户端会显示如下消原创 2020-10-01 21:25:28 · 242 阅读 · 0 评论