Redis应用|青训营

115 阅读4分钟

Redis应用

什么是Redis?

Remote Dictionary Server(Redis) 是一个 key-value 存储系统,它是基于内存的数据库,是跨平台的非关系型数据库。你可以把它作为数据库,缓存和消息中间件来使用。

由于数据量的增长,读写数据压力的不断增加,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈,单台数据库承受四五千 QPS 压力已经很高了。关系型数据库擅长数据持久化存储,并不擅长平常服务高读写的操作,无法应对高并发、高性能、高可用的互联网使用。

数据结构是 key-value,从缓存中读取时,不是输入多个搜索条件来获得匹配的结果,而是输入一个 key 获得一个 value。每份缓存数据是 value,其标识是 key。

安装Redis

访问github.com/tporadowski…,点击Redis-x64-5.0.14.1.zip即可自动下载,下载完成后 ,将其解压缩,在其解压缩后的文件夹运行cmd,输入

redis-server.exe redis.windows.conf

显示以下图片所示即为运行成功。

image-20230815205645976.png 保持此终端页面不要关,再运行一个cmd,输入

redis-cli.exe -h 127.0.0.1 -p 6379

终端变为 127.0.0.1:6379> 证明已经连接到Redis数据库了。

image-20230815205250427.png

操作

指定的 key 不存在时,为 key 设置指定的值:

setnx KEY_NAME VALUE

在原有的数值上+1:

incr KEY_NAME

将 key 中储存的数字值减一

decr KEY_NAME 

删除已存在的键

del KEY_NAME

设置过期时间(在指定时间后过期):

expireat KEY_NAME TIME_IN_UNIX_TIMESTAMP

队列推送:

lpush KEY_NAME VALUE1.. VALUEN

移出并获取列表的最后一个元素:

brpop LIST1 LIST2 .. LISTN TIMEOUT 

返回列表中指定区间内的元素

lrange KEY_NAME START END

同时将多个 field-value (字段-值)对设置到哈希表中

hmset KEY_NAME FIELD1 VALUE1 ...FIELDN VALUEN  

对Hash表中的字段增加值:

hincrby KEY_NAME FIELD_NAME INCR_BY_NUMBER 

返回哈希表中指定字段的值:

hget KEY_NAME FIELD_NAME 

让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除

ltrim KEY_NAME START STOP

移除列表的最后一个元素,返回值为移除的元素:

rpop KEY_NAME

Redis注意事项

大Key(用户访问一个Key的QPS特别高,导致Server示例出现CPU负载突增或者不均的情况)会导致:

客户端执行命令的时长变慢。

Redis内存达到max memory参数定义的上限引发操作阻塞或重要的Key被逐出,甚至引发内存溢出(Out Of Memory)。

集群架构下,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡。

对大Key执行读请求,会使Redis实例的带宽使用率被占满,导致自身服务变慢,同时易波及相关的服务。

对大Key执行删除操作,易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换。

热key(String类型:value的字节数大于10KB即为大key;Hash/ Set/ Zset/ list等复杂数据结构类型:元素个数大于5000个或总value字节数大于10MB即为大key)会导致:

占用大量的CPU资源,影响其他请求并导致整体性能降低。

集群架构下,产生访问倾斜,即某个数据分片被大量访问,而其他数据分片处于空闲状态,可能引起该数据分片的连接数被耗尽,新的连接建立请求被拒绝等问题。

在抢购或秒杀场景下,可能因商品对应库存Key的请求量过大,超出Redis处理能力造成超卖。

热Key的请求压力数量超出Redis的承受能力易造成缓存击穿,即大量请求将被直接指向后端的存储层,导致存储访问量激增甚至宕机,从而影响其他业务。

解决大key的方法

1.拆分 将大key拆分为小key。例如一个String拆分成多个String

2.压缩 将value压缩后写入redis,读取时解压后再使用。压缩算法可以是gzip、snappy、 1z4等。 通常情况下,一个压缩算法压缩率高、则解压耗时就长。需要对实际数据进行测试后,选择一个合适的算法。 如果存储的是JSON字符串,可以考虑使用Message Pack进行序列化。

3.集合类结构hash、list、set (1)拆分:可以用hash取余、 位掩码的方式决定放在哪个key中 (2)区分冷热:如榜单列表场景使用zset,只缓存前10页数据,后续数据走db

解决热key的方法

1.设置local cache 在访问Redis前,在业务服务侧设置local cache,降低访问Redis的QPS。Local Cache中 缓存过期或未命中,则从Redis中将数据更新到local Cache。Java的Guava、 Golang的Big cache就是这类local Cache。

2.拆分 将key : value这一个热Key复制写入多份, 例如key1 : value , key2 : value,访问的时候访问多个key,但value是同一个,以此将QPS分散到不同实例上,降低负载。代价是,更新时需要更新多个key,存在数据短暂不一致的风险。