文章目录
一、Redis是什么?有什么特性?
Redis是NoSQL数据库,即非关系数据库。Redis底层是用C语言写的,用了大量的结构体。特性?先简单说几条吧:
1、Redis是键值对数据库,键是字符串,值是string、list、set、zset、hash等;
2、Redis工作在内存,存取速度非常快,并且能持久化到硬盘,断电可恢复;
3、Redis是单线程、多路复用,用户请求:Redis:CPU = N:1:1。
二、Redis的安装
Redis官方只提供了Linux版本,从官网可下载,上传至Linux OS。安装具体步骤:
1、tar -zxvf redis-xxx解压;
2、进入redis-xxx,使用make命令编译,make install命令安装;
3、通过vi redis.conf进入配置文件,找到“daemon no”改为“daemon yes”,表示以后台方式运行Redis,之后保存退出;
关于redis.conf配置文件
protected-mode no:表示允许远程访问
database 16:默认16个数据库
bind 127.0.0.1:只支持本地访问(注释掉)
4、启动Redis:redis-cli
如图:表示成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cwyo32St-1674007648186)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20230117153635044.png)]
三、一些基本操作
1、键的操作
keys *:查看有哪些键
exists key:查看是否存在某键
type key:值类型
del key:同步删除
unlink key:异步删除
expire key 10:10秒后该key过期,-1表示永不过期,-2表示已经过期
ttl key:查看还有多久过期
select x:切换到x数据库
flushdb:清空当前库
2、string(底层SDS)
set k1 v1:设置键值对(k1,v1)
get k1:获取k1的值
mset k1 v1 k2 v2:设置多个键值对
mget:获取多个键值对
getset:新值换旧值
getrange key 2 3:获取该值第2到第3位的值
3、list(单键多值,底层是双向链表)
lpush:从左边插入值
rpush:从右边插入值
lpop:从左边取出一个值
rpop:从右边取出一个值(值取完了,键就不在了)
rpoplpush:从右边取出一个值放在左边
lindex:获得下标元素
lrange:查看某范围元素
linsert:从某值左边加入一个值
lrem:从左边删除
lset:将某位置元素设置值
4、set(无序、不可重复,底层是hash表)
sadd:添加值
smembers:取出值
sismember:判断是否存在某值
scard:元素个数
spop:随机从集合中吐出一个值
srandmember:随机取出多个值
smove:从一个集合取出到另一个集合
sinter:取两集合的交集
sunion:取两集合并集
sdiff:取两集合差集
5、hash(相当于map<string,object>)
hset:添加数据
hget:取出数据
hmset:添加多条数据
hexists:判断是否存在
hkeys:查看所有key
hvals:查看所有value
hincrby:某值加一个数
hsetnx:设置某值
6、zset(有序、不重复,底层是hash+跳跃表)
zadd:添加值
zrange:取出某范围值
zrangebyscore:按评分取值
zrevrangebyscore:按评分从大到小排序
zincrby:值增加
zrem:删除某元素
zcount:按评分统计
zrank:返回集合中的排名
四、发布和订阅
其实相当于进程间通信。
一个发布者,多个订阅者。订阅者可以订阅某一服务,发布者向该服务发送消息时,各个订阅者都能够收到。常用命令:
subscribe:订阅
unsubscribe:取消订阅
publish:发布
五、新数据类型
1、bitmaps:位操作。适用于较多活跃量的场景。
setbit:设置某一个位的值(0和1)
getbit:取出某个位的值
bitcount:统计位串中1的个数
bitop:做交并补异或操作
2、HyperLogLog:基数(不重复元素)统计。
pfadd:添加元素
pfcount:统计基数数量
pfmerge:合并
3、Geospatial:提供了经纬度操作。
geoadd:添加元素
geopos:读取元素
geodist:直线距离
georadius:某一范围内的值
六、事务
一组操作的集合,要么全部执行成功,要么全部执行失败。
1、锁
(1)悲观锁:每次操作先上锁,解锁后才能被操作。行锁,表锁,读锁,写锁;
(2)乐观锁:给数据加上版本号,操作后版本号变更,若版本号不一致则不能再操作,redis采用乐观锁。
2、watch:对某key进行监视;
unwatch:取消对某key的监视。
3、事务三特性
(1)单独的隔离操作;
(2)没有隔离级别的概念;
(3)不保证原子性
ab测试工具模拟并发
秒杀中超卖和超时:
超卖:加乐观锁(wathch,组队执行)
超时:通过连接池解决连接超时问题
乐观锁引起库存遗留问题:Lua脚本
七、持久化
在指定的时间间隔内将内存中的数据集快照写入磁盘。
1、RDB持久化:按照键值对做持久化,子进程做持久化。先建立一个临时区,将数据同步至临时区(写时复制技术,保证数据一致性),再将数据同步到dump.rdb。
缺点:最后一次持久化的数据可能会丢失;临时区占用较大空间。
2、AOF持久化:只记录写操作,不记录读的操作。Redis重启时加载以恢复数据。
同步频率配置:始终同步,每秒同步,将同步时机交给OS
重写压缩:不关注中间操作,文件大于64M时触发
缺点:要更多磁盘,备份速度慢,性能压力
3、使用哪个?
(1)允许少量数据丢失,可以单独用RDB;
(2)不建议单独用AOF,因为可能出现bug;
(3)如果只是使用缓存,则两者都可以不用。
RDB和AOF同时开启,则默认恢复AOF数据。
八、主从复制(一主多从)
1、读写分离,提升性能。主写从读。
原理:
从服务器连上主服务器后,向主服务器发送数据同步消息;
主服务器收到同步消息后,先进性持久化生成RDB文件,再将RDB文件发给从服务器进行读取;
主服务器写操作后,都会主动和从服务器进行数据同步
2、容灾快速恢复。
3、创建一主多从
修改conf文件
include redis.conf
pidfile redis.pid
port 6379
dbfilename dump.rdb
查看主从服务器:info replication
配置主从:slaveof 主机ip 主机port
4、一主二仆
特点:
(1)从服务器挂掉后,重启变为主服务器,只能手动加入到主服务器。
(2)加入到主服务器后,从头复制主服务器数据。
(3)主服务器挂掉后,从服务器不变。重启后再次变为主服务器。
5、薪火相传
主服务器数据同步从服务器,从服务器再同步到从服务器。
6、反客为主
slaveof no one将从服务器变为主服务器。哨兵模式:反客为主的自动版。
7、哨兵模式
步骤:
sentinel.conf:sentinel monitor master ip地址 port 1(至少有1个哨兵同意切换)
redis-sentinel sentinel.conf 启动redis
原理:
(1)主服务器挂掉,哨兵选择一个从服务器作为主服务器。主服务器重新启动时,变为从服务器。
(2)选择原则:选择优先权大的;优先权相同,选择谁跟主机数据相似度最高的;都相同时,随机选一个。
特点:复制延时。写操作在主机上操作,同步到从机上时会有延时。
九、集群
1、解决问题:容量不足,并发写操作
2、特点:
(1)每个结点存储1/N的数据;
(2)redis推荐的无中心化集群:任何一台服务器都可以作为集群的入口
3、步骤
修改redis.conf文件
include redis.conf
pidfile redis.pid
port 6379
dbfilename dump.rdb
cluster-enable yes
cluster-config-file nodes-xxxx.conf
cluster-node-timeout 15000
redis-cli --cluster create --cluster-replicas 1(以最简单的方式配置集群) ip:port ip:port...
测试:连接:redis-cli -c -p port
cluster nodes
4、其他
(1)分配原则:主服务器不在同一服务器,从服务器不在同一服务器;
(2)slots:一个Redis集群包含16384个插槽,通过算法记录key的值属于哪个插槽,将数据平分到各个服务器。服务器只能查看自己插槽的值。
(3)查询集群中的值:cluster keyslot key
(4)故障恢复:主机挂掉,从机变为主机。之前主机恢复时,将变为从机。
若主机和从机都挂掉了,cluster-requir-full-converage yes时,整个集群都挂掉;设置为no时,该插槽数据不能使用,也无法存储。
(5)Jedis开发集群
创建对象JedisCluster
赋值:jedisCluster.set(key,value)
关闭:close();
5、优缺点
优点:扩容、分摊压力、无中心化
缺点:不支持多键、Lua脚本
十、缓存
1、缓存穿透
(1)现象:应用服务器压力变大了(大量请求),redis命中率降低,一直查询数据库。出现很多url访问,可能遭到攻击(Dos);
(2)解决
空值(Redis未命中的值)做缓存
设置可访问白名单(bitmaps:id比较)
采用布隆过滤器:和bitmaps类似
实时监控:发现redis急速降低,看ip,设置黑名单
2、缓存击穿
(1)现象:数据库访问压力瞬时增加;Redis中的key未出现大量过期且正常运行。原因:某个key过期了,但刚好又大量访问该key;
(2)解决
预先设置热门数据,增加时长
实时调整:热门数据频繁访问时,增加key的过期时长
使用锁
3、缓存雪崩
(1)现象:数据库压力变大;原因:极少的时间段,大量key集中过期。
(2)解决
构建多级缓存架构:Nginx+redis+其他缓存
使用锁:不适合高并发
设置过期标志
缓存失效时间分散开
十一、分布式锁
1、加锁设置值:setnx key value:只能设置一次。因为已经加上了锁,其他主机都只能等待。删除(释放锁):del key
为避免一直锁住,需设置过期时间(expire),过期时间到后自动释放。
综上两步,上锁的原子操作:set key xx nx ex xx
2、Jedis操作
3、问题:
(1)a上锁,在操作时因服务器卡顿操作未完但锁过期,b抢到锁后被a释放。解决方法:设置锁的uuid;
(2)缺乏原子性:a判断uuid相同时,正要删除时,锁被自动释放了,然后被b抢到了,结果a删除了b的锁。解决方法:使用Lua脚本。
十二、新功能
1、ACL:访问控制列表。
acl list:当前用户列表
acl cat:具体的操作命令
acl setuser name:加入用户
acl whoami:查看当前用户
auth username password:切换用户
2、IO多线程
Redis执行命令依然是单线程,只是多路I/O复用。用来处理网络数据的读写和协议解析。
3、工具支持Cluster:Redis5以上环境支持ruby环境。
附:Redis面试题
1、Redis是什么?
Redis是缓存数据库,存储键值对,包含string、list、set、zset、hash基本数据类型。Redis提供RDB和AOF两种持久化方式,将内存中的数据写入磁盘。提供主从复制、集群等功能,保障系统的高可用及可靠性。
2、有哪些使用场景?
(1)通过list取最新的数据;
(2)定时器,过期时间设置,如验证码的过期时间
(3)发布和订阅
3、Redis有哪些功能?
(1)缓存并持久化。
(2)主从复制(一主多从,薪火相传,反客为主,哨兵机制)
(3)集群
4、Redis是单线程吗?为什么?
Redis是单线程,只是是多路复用。单线程不用考虑锁的问题,增加性能。若是多核CPU,则考虑使用多个Redis提高CPU效率。
5、Redis支持的Java客户端
Redission:比jedis封装更丰富
Jedis:封装了Redis的API库,和操作Redis命令相似
6、缓存穿透,缓存击穿,缓存雪崩
(1)缓存穿透:Redis的命中率降低,大量访问数据库,原因可能是Dos攻击。解决方案:将空值存在Redis中,采用布隆过滤器,设置白名单黑名单;
(2)缓存击穿:数据库瞬间访问压力增大,Redis正常。原因可能是某个热点key刚好到期了。解决方案:预先设置热点key的过期时间,增加key的时长,使用锁。
(3)缓存雪崩:大量key过期,数据库访问量增大。解决方案:将key过期时间分散开,使用多级缓存,使用锁。
7、Redis用什么实现分布式锁?用锁会出现什么问题?
原子命令或Lua脚本。
出现的问题:
锁未被释放:设置过期时间
B锁被A锁释放:设置uuid
数据库事务超时:使用Lua脚本
8、Redis如何做内存优化?
(1)缩短键值长度。主要是值的长度,可以从业务上缩短,或者将对象序列化成二进制数组。
(2)共享对象池。
不足之处,恳请指正~