Redis学习日记

Redis是一款高性能的键值存储系统,支持多种数据结构如字符串、哈希、列表、集合、有序集合等。本文详细介绍了Redis的常用命令,包括数据获取、存储、删除、事务操作、主从复制、哨兵模式、持久化策略等。此外,还讨论了缓存穿透、击穿和雪崩问题的解决方案,以及Redis的单线程模型。通过对Redis特性和最佳实践的了解,有助于提升系统性能和数据安全性。
摘要由CSDN通过智能技术生成

Redis命令

get key  #根据key获取value
DBSIZE   #当前DB大小
keys *    #列出当前库所有key
SELECT index  #切换库
FLASHDB  #清空当前数据库
FLASHALL  #清空所有数据库,会触发RDB规则
EXISTS key   #key键是否存在
MOVE key dbindex  #移除数据,一般不用
EXPIRE key   #设置过期时间
TTL key   #查看过期时间
DEL key   #删除key
TYPE key   #查看当前key的类型
APPEND key value   #追加字符串,如果当前key不存在,则新建
STRLEN key   #字符串长度
INCR key  #加1
DECR key  #减1
INCRBY key size   #加size
DECRBY key size   #减size
GETRANGE key start end   #截取字符串,offset传-1表示查出整个字符串,[start,end]
SETRANGE key offset value  #替换字符串(下标从1开始算,offset表示偏移量)
SETEX key time value   #set字符串time秒后过期
SETNX key value   #不存在则创建,存在不会被覆盖,分布式锁使用
mset k1 v1 k2 v2 k3 v3   #批量set
mget k1 k2 k3   #批量获取
msetnx   #msetnv是原子性操作
getset   #先get在set

List命令(所有的List命令都是l开头的)(头部插入倒序集合)

LPUSH list v1 v2 v3   #批量从头部插入
LRANGE list start end   #获取列表start到end(下标从0开始)
RPUSH list v1 v2 v3   #尾部批量插入
lpop list   #从头部移除一个元素
rpop list   #从尾部移除一个元素
lindex list index   #获取列表指定位置(index下标)的值
llen list   #获取列表长度
lrem list count value   #移除列表中count个制定的value值
ltrim list start end   #截取/保留列表start到end
rpoplpush source destination   #从source尾部移出一个元素到des列表中
lset list index value   #set指定下标的值(list不存在会报错)
linsert list before|after pivot value   #在列表privot前或后

Set命令(无序集合,不能重复)

sadd set v1 v2 v3   #往set集合添加元素
smembers set   #获取set所有元素
sismember set value   #判断value是否在set集合中
scard set   #获取集合set大小
srem set v1 v2 v3   #批量移除set中指定value值元素
srandmember set [count]   #随机获取set中一[count]个元素
spop set [count]   #随机移除一[count]个元素
smove source destination value   #移动指定value元素到另一个集合中
sdiff set1 set2   #集合中的差集
sinter set1 set2   #集合中的交集
sunion set1 set2   #集合中的并集

Hash命令

hset key field value   #set一个f-v键值对
hget key field   #根据field键获取值value
hmset key f1 v1 f2 v2   #批量set键值对
hmget key f1 f2   #批量获取值
hgetall key   #获取所有hash值
hdel key f1 f2   #批量删除key中的hash键值对
hlen key   #获取大小
hexists key field   #判断field是否存在
hkeys key   #获取所有的field
hincrby key field count   #value值增加count
decrby key field count   #value值减少count
hsetnx key field value   #如果field不存在则创建,存在不覆盖

Zset(有序集合)命令

zadd key index value   #添加一个值,index为排序优先级
zadd key i1 v1 i2 v2   #批量添加
zrange key start end   #获取集合元素(以index排序后输出)
zrangebyscore key min max [withscores]   #按index排序后获取(min-max)范围元素,-inf为负无穷[同时输出index]
zrem key value   #移除元素
zcard key   #获取集合大小
zrevrange start end   #获取集合元素,当end<start则倒序
zcount key min max   #获取index指定区间的集合数量

Geospatial命令(地理位置)

geoadd key longitude latitude member   #添加key的经度 纬度 名称
geopos key member   #获取指定位置的经纬度
geodist key m1 m2 [unit]   #两个位置的距离[单位]
georadius key longitude latitude count unit [withdist] [withcoord]   #查看方圆半径的位置[距离][经纬度]
georadiusbymember key member count unit   #以member为中心count范围的位置名称
geohash key m1 m2   #将地理位置转化为字符串

Hyperloglog命令(基数统计,内存小,0.81%误差)

pfadd key element   #添加元素
pfadd key e1 e2   #批量添加元素
pfmerge des source1 source2   #批量合并并去重
pfcount k1 k2   #统计基数数量(并集数量)

Bitmap(位图)

setbit key offset value   #添加位图,value只有0和1
getbit key offset   #获取位图
bitcount key [start,end]   #统计value为1的记录

其他命令

ping   #测试链接
config get requirepass   #获取密码
config set requirepass   #设置密码
auth   #验证密码获取权限
config get dir   #运行目录

优点

1、适合大规模的数据恢复!
2、对数据的完整性要求不高!

缺点

1、需要一定的时间间隔进行操作!如果redis意外宕机,最后一次修改数据就丢失了!
2、fork进程的时候,会占用一定的内存空间!

事务( Redis单条命令保证原子性,但是事务不保证原子性!)

事务的本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
一次性、顺序性、排他性!
  • 开启事务(multi)

  • 命令入队(...)

  • 执行事务(exec)

  • 放弃事务(discard)

命令错误时事务回滚,语法性错误会继续执行

Redis监视器

多线程修改值时,使用watch可以当做redis的乐观锁,一旦有其他线程做了修改,事务会提交失败

watch key   #监视key
multi   #开启事务
exec   #提交事务
unwatch   #放弃监视

redis.config

网络network

bind   #绑定的IP,即可访问redis的IP
protected-mode   #保护模式
port   #端口

通用general

daemonize   #是否守护进程,yes为后台运行
pidfile   #如果以后台的方式运行,就需要指定一个pid文件
logfile   #日志文件位置名
databases   #数据库数量
always-show-logo   #是否显示logo
​

快照SNAPSHOTTING

save 900 1   #表示900秒内有1个key进行修改,就进行持久化操作
stop-writes-on-bgsave-error   #持久化出错是否继续工作
rdbcompression   #是否压缩rdb文件,会消耗CPU资源
rdbchecksum   #保存RDB的时候是否进行错误校验
dir   #rdb文件保存的目录

复制REPLICATION

安全SECURITY

requirepass   #redis密码

客户端CLIENTS

maxclients   #最大客户端数量
maxmemory <bytes>   #最大内存
maxmemory-policy noeviction   #内存达到上线的处理策略
        #1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
        #2、allkeys-lru : 删除lru算法的key   
        #3、volatile-random:随机删除即将过期key   
        #4、allkeys-random:随机删除   
        #5、volatile-ttl : 删除即将过期的   
        #6、noeviction : 永不过期,返回错误

APPEND ONLY MODE(aof)

appendonly no   #是否开启aof,默认不开启,使用rdb持久化
appendfilename "appendonly.aof"   #持久化文件名
# appendfsync always   #每次修改都执行sync同步
appendfsync everysec   #每秒执行sync同步一次
# appendfsync no   #不执行sync,操作系统自己同步,性能最好

持久化

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

RDB

dbfilename dump.rdb   #RDB文件名,FLASHALL会触发RDB规则

AOF

appendonly no   #aof是否开启,默认不开启
# appendfsync always   #每次都同步
appendfsync everysec   #每秒同步
# appendfsync no   #不同步,操作系统自己同步数据
redis-check-aof --fix xxx.aof   #修复aof文件

AOF缺点

1、aof文件比rdb文件大得多,修复速度比rdb慢

持久化总结

1、RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储

2、AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.

 Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

3、只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.

4、同时开启两种持久化方式

(1)在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
​
(2)RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?
        作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。

5、性能建议

(1)因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。 (2)如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。 (3)如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构 ———————————————— 版权声明:本文为CSDN博主「大雄号」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_27339781/article/details/80725921

Redis发布订阅

 

主从复制(至少一主二从)

1、数据冗余:主从复制实现了热备份,是持久化之外的一种冗余方式。
2、故障恢复:当主节点出现问题时,可由从节点,实现快速的故障恢复。
3、负载均衡:在主从复制的基础上,实现读写分离,由主节点提供写服务,从节点提供读服务。
4、高可用:主从复制是哨兵模式和集群能够实施的基础,因此说主从复制是高可用的基础。

命令

info replication   #查看当前库的信息
#   # Replication
#   role:master   #角色
#   connected_slaves:0   #从机数量
slaveof ip port   #认主机,ip端口为主机地址
slaveof no one   #恢复主机

配置

replicaof <masterip> <masterport>   #从机配置主机地址

复制原理

Slave启动成功连接到master后会发送一个sync命令; Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步; 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中; 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步; 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行; ———————————————— 版权声明:本文为CSDN博主「Java小林」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/DengShengL/article/details/104583835

哨兵模式

用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。如果主机恢复,会归并到新选举的主机下当从机。

作者:秃头哥编程 链接:https://www.jianshu.com/p/06ab9daf921d 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

缓存穿透

描述:访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上。

此时,缓存起不到作用,请求每次都会走到数据库,流量大时数据库可能会被打挂。此时缓存就好像被“穿透”了一样,起不到任何作用。

解决方案:

1、接口校验。在正常业务流程中可能会存在少量访问不存在 key 的情况,但是一般不会出现大量的情况,所以这种场景最大的可能性是遭受了非法攻击。可以在最外层先做一层校验:用户鉴权、数据合法性校验等,例如商品查询中,商品的ID是正整数,则可以直接对非正整数直接过滤等等。

2、缓存空值。当访问缓存和DB都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间,该时间需要根据产品业务特性来设置。

3、布隆过滤器。使用布隆过滤器存储所有可能访问的 key,不存在的 key 直接被过滤,存在的 key 则再进一步查询缓存和数据库。

缓存击穿

描述:某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。

解决方案:

1、加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。

2、热点数据不过期。直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存。

这种方式适用于比较极端的场景,例如流量特别特别大的场景,使用时需要考虑业务能接受数据不一致的时间,还有就是异常情况的处理,不要到时候缓存刷新不上,一直是脏数据,那就凉了。

缓存雪崩

描述:大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂。

缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key。

解决方案:

1、过期时间打散。既然是大量缓存集中失效,那最容易想到就是让他们不集中生效。可以给缓存的过期时间时加上一个随机值时间,使得每个 key 的过期时间分布开来,不会集中在同一时刻失效。

2、热点数据不过期。该方式和缓存击穿一样,也是要着重考虑刷新的时间间隔和数据异常如何处理的情况。

3、加互斥锁。该方式和缓存击穿一样,按 key 维度加锁,对于同一个 key,只允许一个线程去计算,其他线程原地阻塞等待第一个线程的计算结果,然后直接走缓存即可。

Redis是单线程的 (QPS 10W+)

Redis是基于内存操作,CPU不是Redis的内存瓶颈,是由内存和带宽决定的,多线程会引起CPU上下文切换(耗时),所以Redis就使用单线程实现了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值