标签:编写 同步 cat 工作过程 hash 恢复 更新 sed obj
标签(空格分隔): SQL
Redis是基于内存的高性能
key-value
数据库.
String, Hash, List, Set, Sorted Set.
Redis内部使用一个RedisObject对象来表示所有的
key
和value
.
value
对象具体是哪一种数据类型.type = String
代表value
存储的是一个普通字符串, 那么对应的encoding
可以使raw
或者是int
, 如果是int
则代表实际redis
内部是按照数值型类存储和表示这个字符串的, 当然前提是这个字符串本身可以用数值表示如"123"
, "345"
这样的字符串.Redis内存淘汰机制指的是用户存储的一些键可以被Redis主动的从实例中删除, 从而产生读
miss
的情况, 那么Redis
为什么要有这种功能呢? 这就是我们需要探究的设计初衷.Redis
最常见的两种应用场景为缓存
和数据持久存储
. 首先需要明确的一个问题是内存淘汰策略更适合于那种场景? 是持久存储还是缓存?
假设我们有一个Redis服务器, 服务器的物理内存大小为1G
, 我们需要存在Redis
中的数据量很小, 这看起来似乎足够用很长时间了, 但是随着业务量的不断增长, 我们在其中放的数据也会越来越多, 数据量大小似乎超过了1G
, 但是应用还可以正常运行, 这是因为操作系统的课件内存并不受物理内存的限制, 而是虚拟内存, 当物理内存不够用的时候, 操作系统会在硬盘上面划分出来一块虚拟内存, 那么这个时候我们的可用内存就是2^32
大约为3G
, 但是这个时候会在物理内存和虚拟内存之间发生频繁的内存交换(在访问虚拟内存中的数据的时候). 这种交换会严重的降低磁盘性能 和 Redis读写数据的性能. 所以我们需要一定的miss
来换取内存的使用效率.
作为Redis用户我们如何使用Redis提供的这个特性呢?
maxmemory <bytes>
我们可以通过配置redis.conf
中的maxmemory
这个值来开启内存淘汰功能, 至于这个值有什么意义, 我们可以通过了解内存淘汰过程来了解.
maxmemory
则根据用户配置的淘汰策略来淘汰key
, 从而换取一定的内存.maxmemory
为0的时候表示我们的Redis的内存使用没有限制.内存淘汰是Redis
提供的的一个功能, 为了更好的使用这个功能必须为不同的应用场景下提供不同的策略, 内存淘汰策略讲的是为实现内存淘汰策略我们应该具体怎么做, 要解决的问题包括键空间怎么选择, 在键空间中淘汰键如何选择?
noevication
策略:key
.下面看看几种策略的具体适用场景:
allkeys-lru
: 如果我们应对缓存的访问符合幂律分布(也就是存在相对热点), 或者我们不太清除我们应用缓存访问分布状况, 我们可以采取allkeys-lru
. 相对于volatile-lru
占用的内存空间更低.volatile-lru
: 策略适合我们将一个Redis实例即应用于缓存又应用于数据持久化的时候, 然而我们也可以通过使用两个Redis实例, 来达到相同的效果, 值得一提的是将key
设置的有过期时间的时候实际上会消耗更多的内存(主键空间/设置了过期时间的主键空间).allkeys-random
: 如果我们的应用对于缓存key
的访问概率相等的话, 则可以使用这个策略.volatile-random
: 策略适合我们将一个Redis实例即应用于缓存又应用于数据持久化的时候, 然而我们也可以通过使用两个Redis实例, 来达到相同的效果, 值得一提的是将key
设置的有过期时间的时候实际上会消耗更多的内存(主键空间/设置了过期时间的主键空间).volatile-ttl
: 使得我们可以向Redis提示那些key
更适合被eviction
上面提到的LRU(Least Recently Used)策略, 实际上Redis实现的LRU并不是可靠的LRU, 也就是名义上我们使用LRU算法淘汰键, 但实际上被淘汰的键并不一定是真正的最久没用的, 这里涉及到一个权衡的问题, 如果需要在全部键空间内搜索最优解, 则必然会增加CPU的负载, 但是因为Redis是单线程的, 也就是同一个实例在每一个时刻只能服务于一个客户端, 所以耗时的操作一定要谨慎. 为了在一定成本内实现相对的LRU, 早起的Redis版本是基于采样的LRU, 也就是放弃全部键空间内搜索解改为采样空间内搜索最优解. 自从Redis3.0之后,其作者对LRU算法进行了优化, 目的就是在一定的成本内得到的结果更加接近真实的LRU.
如果有人恶意的向服务器获取并不存在的数据, 这个时候Redis服务器就不产生作用了, 如果发生大量这样的情况的时候, 会给数据库带来巨大的压力.
实现流程如下:
实际上在工作过程中, 如果第五步发现对象为空的时候, 会给该对象的值设为空, 存储到缓存中, 并且设置过期时间(60S).
在某一个时间段, 缓存集中过期失效. 例如电商项目, 在某个时间段 大量的商品被放入缓存, 然后它们又集体过期, 这个时候如果有查询的话会给数据库带来比较大的压力. 造成缓存雪崩.
在存入缓存的时候, 在设置的过期时间上可以加上一个随机数, 防止集体过期这种情况出现. 随机数在热门资源上可以长一点, 冷门资源上可以短一点.
某一个非常热门的资源在缓存数据库中, 如果某个时间点该缓存过期会造成大量线程去数据库访问并缓存该资源, 一般情况下是不会产生这样的情况的, 如果出现这种情况可以直接设置永不过期(更新数据的时候另操作), 或者使用mutex key
互斥锁.
高可用集群, 是保证业务连续性的有效解决方案, 一般有两个或者两个以上的节点, 且分为活动节点和备用节点. 通常把正在执行业务的成为活动节点, 而作为活动节点的一个或多个备份成为备份节点. 当活动 节点出现问题的时候导致正在运行的业务中断, 备用节点此时就会侦测到, 并理解使用备用节点执行也许, 从而实现业务的连续性.
Redis一般以主/从方式部署(这里讨论的从实例
主要用于备份, 主实例提供读写) 实现HA主要有如下几种方案:
redis.clients.jedis.JedisSentinelPool.getResource()
取得的Jedis实例会及时更新到新的主实例地址.标签:编写 同步 cat 工作过程 hash 恢复 更新 sed obj
原文地址:https://www.cnblogs.com/A-FM/p/12673949.html