文章目录
1.Redis基本知识
- redis是单线程的,为什么还这么快呢。
因为redis是基于内存操作的,所以CPU不是它的瓶颈,它的瓶颈是机器的内存和网络的带宽 - 核心:redis是将所有数据全部存在内存中的,所以单线程效率很高。多线程会造成CPU上下文切换,很耗时。
2.Redis数据结构
1.Hash
String Key和String Value的map容器
常用命令:赋值,删除,取值,增加数字
- hset myhash username jack(设置一组值)
- hset myhash age 18
- hmset myhash2 username rose age 21(设置多组值)
- hget myhash username ---------jack
- hmget myhash username age--------jack 18
- hgetall myhash ----------username jack age 18(获取所有属性)
- hdel myhash2 username age(删除字段)
或者del myhash2 - hgetall myhash2--------empty
- hincrby myhash age 5
- hget myhash age-----------23
- hexists myhash username------------1(字段是否存在)
- hexists myhash userpassword-------------0
- hlen myhash------------------2(有几个字段/字段长度)
- hkeys myhash---------------username age(获取所有字段)
2.String字符串
常用命令:赋值,取值,删除,数值增减
- set company imooc
- get company----------------imooc
- getset company baidu
- get company--------------baidu
- set person jack
- get person-----------------jack
- append K V--------------将值追加到value后
- incr K---------------将K对应的V加1
- incrby K int------------将K对应的V自增int的值
- getrange K start end-----------查看范文内地V
- setrange K start end----------替换范围内的值
- setex K int---------设置K的过期时间为int
- setnc K V-----------不存在就创建,存在就不创建
- mset K1 V1 K2 V2---------批量设置
- set user:1:name zhangsan----------设置K=user:1:name,V=zhangsan。在项目中有用处
3.存储list
ArrayList使用数组方式
LinkedList使用双向链接方式
双向链表中增加数据
双向链表中删除数据
常用命令:两端添加,查看列表,两端弹出,获取列表元素数
- lpush mylist a b c--------------3(左端添加三个元素abc,显示元素个数为3)
- lpush mylist 1 2 3--------------6
- lrange mylist 0 5------------3 2 1 c b a(输出0-5位置的元素)
- lpop mylist ------------3(弹出的左端第一个,值为3)
- llen mylist------------5(返回元素个数)
- lindex list int------------获取list中的int位置的值
- ltrim list int int------------只保留范围内的值
4.Set
和List不同,Set不允许出现重复元素
常用命令:添加删除,获取集合中元素,集合中差集运算,交际运算,并集运算
- sadd myset a b c-----------------3
- sadd myset a-------------error(不能存重复数字)
- sadd myset 1 2 3
- srem myset 1 2 (删除元素)
- smembers myset-------c b a 3(显示元素)
- sismembers myset a-------------1(判断元素是否存在,1为存在,0为不存在)
- sadd mya1 a b c
- sadd myb1 a c 1 2
- sdiff mya1 myb1----------b(差集运算,myb1中无b)
- sdiff myb1 mya1----------1,2(mya1中无1,2)
- sinter mya1 myb1---------a,c(交集,都有的)
- sunion mya1 myb1-----c 2 b a 1(并集)
5.ZSet
5.Bitmaps位存储
bitmap位图,只有0和1两个状态
- set K 位数 V------------设置K中第几位的值为V。如K为某员工,位数为星期数,签到为1,未到为0.
set wxz 1 1
set wxz 2 0
set wxz 3 1
3. Redis持久化
1.RDB(Redis Database)(更优)
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束了,在用这个临时文件替换上次持久化的文件。整个过程中,主进程不进行任何IO操作,确保了极高的性能。如果需要进行大规模数据的回复,且对于数据恢复的完整性不敏感,那RDB方式比AOF更加的高效。
触发机制:
- save的规则满足的情况下,会触发
- 执行flushall,会触发rdb规则
- 退出redis,也会产生rdb文件
备份就会自动生成rdb文件
只要将rdb文件放在redis启动目录下,redis会自动加载它
优点:
- 适合大规模数据的恢复
缺点:
- 对数据的完整性要求不高(因为它是每隔一段时间自动save,就会自动产生rdb,如果意外宕机,则有可能造成数据丢失)
- fork进程的时候,会占用一定空间。
2.AOP(Append Only File)
文件:appendonly.aof
把我们的所有命令都记录下来,恢复的时候就把这个文件全部在执行一遍。
默认不开启
以日志的形式来记录每个写操作,将Redis 执行过的所有指令记录下来(读操作不记录),只许追加文件但不可改写文件,redisi启动后会读取该文件重新构建数据。换言之,redis重启的话就根据日志文件将写指令从前到后执行一次完成数据的恢复。
如果aof文件有错位,这时redis是启动不起来的。这是redis提供了工具redis-checkout-aof --fix
优点:
- 设置每次修改都同步,文件的完整性更好
- 设置每秒同步一次**(默认)**,可能会丢失一秒的数据
- 设置从不同步,效率最高
缺点:
- 相对于数据文件来说,aof远大于rdb
,修复速度也更能慢 - aof运行效率也比rdb慢,所以redis默认是rdb持久化
4.Redis主从复制
主从复制是指将一台Redis服务器的数据,复制到其它Redis服务器,前者称为主节点(Master),后者为从节点(slave)。数据的复制是单向的,只能从主到从。
master以写为主,slave以读为主因为80%都是读操作,这样可以减少主机压力
主从复制作用:
- 数据冗余
- 故障恢复
- 负载均衡
- 高可用基石
1.手动模式
环境配置
-
redis默认自己就是一个主库,所以我们只需要配置从库。
-
单机多集群:复制主服务器的conf两份并改名,然后修改端口,pidfile,log,dump文件即可。
-
然后在两个子服务器界面 salveof 端口号即可将此端口号作为自己的主机 。
主机进行写操作,从机只能读。主机在添加数据后,从机会自动加载。
主机断开,从机依旧连接到主机。当主机恢复后,还可继续操作。
如果使用命令行配置的从机,那么从机断开后,再次重连时,自己会变为主机。
2.哨兵模式
哨兵作用:
- 通过发送命令,让Redis服务器返回监控器运行状态,包括主服务器和从服务器。
- 当哨兵检测到master宕机,会自动将slave切换到master,然后通过发布订阅模式通知其他从服务器,修改配置文件,让他们切换主机。
然而一个哨兵对整个服务集群进行监控难免哨兵会出问题。因此我们采用多个哨兵进行监控,形成多哨兵模式。
假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failober过程,此时仅仅时哨兵1认为主服务器不可用,这个过程是主观下线。当其他哨兵也检测到这个情况并达到一定数量时,会进行一次投票(内置算法),进行failover(故障转移)操作。切换一个从变为主,通过订阅者模式发布消息,让其他从服务器重新认老大。这个过程是客观下线。
配置哨兵文件sentinel.conf
sentinel monitor 主机名称 127.0.0.1 6379 1
后面这个1代表主机挂了,slave投票看让谁接替主机
启动哨兵:在根目录下输入redis-sentinel kconfig/sentinel.conf
会自动监测到主机及其从机
4.Redis缓存穿透,击穿和雪崩
1.缓存穿透(查不到)
概念:用户查一个数据,redis中没有,也就是缓存没有命中,于是向持久层数据库查询,发现也没有,于是查询失败。当在大用户量的情况下,直接访问数据库会带来很大压力,这就是缓存穿透。
解决方案:
- 布隆过滤器:是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先校验,不符合则丢弃,从而避免了对底层数据库的压力。
- 缓存空对象:设置空对象,防止用户直接查询数据库。缺点是浪费时间。
2.缓存击穿(可以查到,量太大或缓存过期)
概念:指一个非常热点的K,一直扛着高并发,在K失效的瞬间,持续的大并发击穿缓存,冲向数据库。
解决方案:
- 设置热点数据永不过期
- 加互斥锁
3.缓存雪崩
概念:指某一时间段,缓存集中过期或Redis宕机。
解决方案:
- 停到一些服务,保持Redis高可用,搭建Redis集群
- 限流降级:通过加锁或者队列来控制线程数量
- 数据预热:在正式部署前,把可能的数据预访问一边,将它们加入缓存。设置缓存失效的时间点尽量均匀,不要集中。