redis整理超详细
Redis支持的五大数据类型包括
String(字符串 用法: 键 值),
Hash(哈希 类似Java中的 map 用法: 键 键值对),
List(列表 用法:键 集合 不可以重复),
Set(集合
话不多少 先上图 Redis支持的五大数据类型包括 String(字符串 用法: 键 值), Hash(哈希 类似Java中的 map 用法: 键 键值对), List(列表 用法:键 集合 不可以重复), Set(集合 用法:键 集合 可以重复), Zset(sorted set 有序集合 用法: 键 值 值) 单线程,多线程 在一开始的时候,Redis采用的是单线程模型,因为Redis是一个基于内存的数据库,将所有的数据放入内存,所以使用单线程的操作效率是最高的, 多线程会上下文切换消耗大量时间,对于内存系统来说,单线程才能产生更高的效率。但是单线程不意味着整个Redis就一个线程,Redis其他模块还有各自的线程 Redis基于内存操作,CPU并不是性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽。在6.0的版本中引入了多线程。 这个I/O threads 指的是网络I/O处理方面使用了多线程,如网络数据的读写和协议解析等,这是因为读写网络的read/write在Redis执行期间占用了大部分CPU时间,如果把这部分模块使用多线程方式实现会对性能带来极大地提升。但是Redis执行命令的核心模块还是单线程的。 目前最新的6.0版本中,I/O多线程处理模式需要在配置文件中开启。 单线程为什么快 1. 纯内存操作 2. 单线程操作避免了上下文的切换 3. 采用了非阻塞i/o多路复用机制 Redis大部分操作在内存完成 采用IO多路复用机制 非CPU密集型任务 单线程的优势 Redis大部分操作在内存完成 采用了非阻塞i/o多路复用机制 单线程操作避免了上下文切换导致的性能损耗 避免多线程上下文切换导致的性能损耗 避免多线程访问共享资源加锁导致的性能损耗 所以Redis正是基于有以上这些优点,所以采用了单线程模型来完成请求处理的工作。 雪崩,穿透,击穿 一、缓存穿透 1.问题描述: 在查询一个一定不存在的数据时,由于数据库中没有,不会缓存到redis中,所以缓存百分百不会命中,将去数据库中查询,数据库也没有此记录,循环往复,每次查询缓存无法命中,对数据库(数据存储层)造成压力,失去了缓存的意义。 2.风险: 利用数据库中不存在的数据,进行恶意攻击,数据库瞬时压力增大,导致数据库崩溃。 3.解决办法: 将查询到的null结果也缓存到redis中,并加入短暂的过期时间 最常见的则是采用布隆过滤器,将所有可能存在的数据哈 希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存 储系统的查询压力。 二、缓存雪崩 1.问题描述: 缓存雪崩是设置缓存时,设置了相同的过期时间,在大并发量不间断的访问下,缓存在某一时刻全部失效,此时所有的查询压力都会分配到数据库,数据库瞬时压力过大导致雪崩。 2.解决办法: 在原有的失效时间基础上,增加一个1-5分钟随机值,使其缓存时间不一样,减少重复率,减小数据库查询压力,降低了集体缓存失效的概率。 一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。 给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。 三、缓存击穿 1.问题描述: 对于热点数据来说,在不间断的大并发量情况下,还设置了过期时间,可能在失效的那一瞬间,被高频访问,此时redis中的缓存已经失效,所有查询压力都会落到数据库上,这种现象就叫做缓存击穿。 2.解决办法: 加锁处理。 思路:大量并发前来查询,只让一个线程去数据库查询,其他线程等待,查到后该线程释放锁,其他人获取锁,在获取到锁后,先查寻redis缓存中是否有数据,如果没有为第一个获取到锁的线程,查询数据库;有数据则直接返回。 减少重复率,减小数据库查询压力,降低了集体缓存失效的概率。 Redis key的淘汰策略有哪些 no evictionno??v?k?n Redis 默认淘汰策略,对于写请求不再提供服务php单线程,直接返回错误( DEL 请求和部分特殊请求除外) all keys - lru 从所有 key 中使用 LRU 算法进行淘汰 volatile - lru 从设置了过期时间的 key 中使用 LRU 算法进行淘汰 all keys - random 从所有 key 中随机淘汰数据 volatile - random 从设置了过期时间的 key 中随机淘汰 volatile - ttl 从设置了过期时间的 key 中,根据 key 的过期时间进行淘汰,越早过期的越优先被淘汰 当使用volatile-lru、volatile-random、volatile-ttl这三种策略时,如果没有key可以被淘汰,则和noeviction一样返回错误 LRU算法 又称最近最少使用算法,它的基本思想是长期不被使用的数据,在未来被用到的几率也不大,所以当新的数据进来时我们可以优先把这些数据替换掉。 key的删除策略 定时删除 含义:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除 优点:保证内存被尽快释放 缺点:若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key 定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重没人用 惰性删除 含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。 优点:删除操作只发生在从数据库取出key的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的key了) 缺点:若大量的key在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存) 定期删除 含义:每隔一段时间执行一次删除过期key操作 优点:通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用 缺点:在内存友好方面,不如"惰性删除" 在CPU时间友好方面,不如"定时删除" 难点:合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)(这个要根据服务器运行情况来定了) redis锁的两种意外 a.如果redis中的锁已经过期了,然后锁过期的那个请求又执行完毕,回来删锁,删除的是其他线程的锁,怎么办? 答案:用key获取value值,判断value值与set时是否一致 b.如果碰巧在查询redis锁还没有删除的时候,正在网络传输时,锁过期了,怎么办? jedis.eval(“lua”);可与用lua脚本,在查询到key的同时删除该key,防止高并发下的意外的发生 redis内存优化方案 lru 1、缩减key和value的长度。key尽量简写如s:a:id。value不存储不需要数据。 2、开启共享内存池,纯数字数据可以公用内存。但是无法使用过lru的内存淘汰策略 3、如果编辑数据长度变化较大,尽量删除后重新存储。因为redis的预分配机制,追加操作,将会预留更大的存储空间。 4、尽量使用复杂度更低的编码方式,编码方式不可逆。如果数据变简单,情况允许,可以重新创建。 5、控制hash中键的数量。数量最好不要超过1000。因为ziplist编码,超过1000后,cpu消耗增加 先整理到这吧 一句话 想要学好还是要先看底层 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |