redis-pipeline机制
pipeline是Redis的一个提高吞吐量的机制,适用于多key读写场景,比如同时读取多个key的value,或者更新多个key的value。因为redis本身是基于Request/Response协议的,在正常情况下,客户端发送一个命令,等待Redis返回结果,Redis接收到命令,处理后响应。如果进行多次的读和写数据到redis,每次都建立一个链接,这样是比较消耗资源的,而且也比较忙,于是想到了管道机制,只建立一个连接,然后批量执行读或写。
pipeline每次只作用在一个redis节点上,所以如果做了集群,也就没办法使用pipeline了,因为开了集群之后就不是一个节点,他就不知道该放到哪个上面了。
redis-事务
redis可以用pipeline来实现事务,但是redis的事务和mysql的事务不一样,不保证数据安全。对于redis来说,单条命令是保证原子性的,但是整个事务是不保证的,且没有回滚,如果前面的语句失败,后面的照样执行。
multi 开启事务
exec 执行事务
discard 放弃事务
redis-乐观锁
redis没有悲观锁,只能实现乐观锁,因为加锁有可能会造成长时间的等待,所以Redis为了尽可能地减少客户端的等待时间,并不会在执行WATCH命令时对数据进行加锁。要实现乐观锁也很简单,在事务开始前,先watch要修改的key,如果在事务执行过程中,整个key被修改了,那么这个事务就会执行失败,实现了乐观锁。
redis-缓存更新策略
LRU -Least Recently Used,没有被使用时间最长的
LFU -Least Frequenty User,一定时间段内使用次数最少的
FIFO -First In First Out,先进先出
redis-你项目缓存怎么更新
就是我们使用redis的时候,缓存和数据库之间的数据一致性。
常见的更新策略:
- 先删缓存,再更新数据库
- 先更新数据库,再删缓存(目前常用)
- 先更新数据库,再更新缓存
- read/write through
- 写回。在更新数据的时候,只更新缓存,不更新数据库,而我们的缓存会异步地批量更新数据库
redis-持久化策略
redis因为是基于内存的,如果redis重启数据就没了,所以他配置了持久化策略。redis提供了两种方式,RDB和AOF,两中的开启方式一般是在配合文件中配置,也可以通过redis的命令。
RDB
RDB有三种触发方式,save,bgsave,还有配置文件自动化。
save:这个命令会阻塞当前的redis服务器,在RDB完成过程中,redis不能处理其他命令,这个方式不可取。
bgsave:是一个异步执行,redis会在后台异步进行快照,把所有数据完成一个备份,然后父进程fork一个子进程来保存这个文件,这期间只有fork子进程的时候会阻塞,时间基本很短。
配置文件:在配置文件配置好RDB的持久化规则,然后redis会按照配置文件执行。默认的我记得是900 1,300 10这样的。
RDB的优势:文件紧凑,是全部备份,且RDB的恢复大数据集的速度比AOF快
RDB缺点:如果系统在持久化的时候宕机,那么没来得及写入磁盘的数据回丢失
AOF
每写入一条命令,都记录一条日志,放到日志文件中,如果出现宕机,可以将数据完全恢复。aof有两种触发方式
配置文件自动化:配置文件有三种策略,
always每次数据修改都写入aof,是同步持久化,不会丢失数据,但是效率低
everysec异步操作,每秒同步一次,会丢失一秒数据
no不同步
AOF优点:数据比RDB安全,当日志文件过大的时候,会
AOF缺点:AOF文件体积比RDB大,根据选择的持久化策略,AOF的速度可能慢与RDB
redis-AOF重写
当aof文件过大的时候,我们可以通过AOF重写来优化持久化文件,本质就是把一些无用的,重复的命令优化一下。比如rpush list1 1,rpush list1 2,rpush list1 3,经过aof重写就可以变成有一句,rpush list1 1,2,3。
aof重写两种方式:
1、当我们在客户端使用bgrewriteaof命令时,服务端就会起一个子进程,完成aof重写。
2、在配置文件设置,有几个参数配置一下,我记得大概是文件增长率,还有大小等。
redis-规避缓存风险
正常情况下我们的业务请求进来时,先查询Redis,如果Redis中存在的话,直接返回Redis中结果;如果Redis中不存在的话,访问数据库。
在高并发的场景下,缓存会出现一些风险。比如缓存雪崩,缓存击穿,缓存穿透。
缓存雪崩:在某个时刻,缓存大面积失效,导致所有请求都打到数据库。
缓存击穿:在某个时刻,单个热点key过期,导致许多请求打到数据库查询。
缓存穿透:指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方案:
雪崩:
1、缓存数据的过期时间随机设置
2、热点数据设置永不过期
3、如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
击穿:
1、设置数据永不过期
2、基于redis实现互斥锁,第一个进来的线程拿着锁去数据库查,查出来之后缓存下来,后面的请求判断有缓存了就直接走缓存
穿透:
1、使用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap(位图)中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
2、将该ip拉黑,这个方案一般是没用的,因为既然是恶意攻击,肯定可以换ip
3、对于不存在的数据,缓存到redis中,设置key,value值为null,并设置一个短期过期时间,避免时间过长影响正常用户。说白了就是将击透的key缓存起来,但是时间不能太长,下次进来是直接返回不存在,但是这种情况无法过滤掉动态的key,就是说每次请求进来都是不同的key,这样还是会造成这个问题
4、对参数进行校验,不法参数直接拦截
redis-主从复制
redis-哨兵
redis-分布式集群
redis-基础类型和应用场景
str:做缓存,计数器
list:做消息队列
hash:存用户数据,模拟关系型数据库
set:做共同好友,做用户标签
zset:排行榜,限流
redis-高级类型和应用场景
Geospatial:地理位置,可以做定位,做附近的人,打车
Hyperloglog:基数统计,访问量统计,去重
Bitmap:操作二进制来进行记录,打卡,活跃与不活跃用户,登录与未登录
redis-跳跃表
Redis使用跳跃表作为有序集合键的底层实现之一,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员是比较长的字符串时, Redis就会使用跳跃表来作为有序集合健的底层实现。
redis-布隆过滤器
redis-主从同步原理
- 副本库通过slaveof 127.0.0.1 6379命令,连接主库,并发送SYNC给主库
- 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
- 副本库接收后会应用RDB快照
- 主库会陆续将中间产生的新的操作,保存并发送给副本库
- 到此,我们主复制集就正常工作了
- 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库.
- 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在.
- 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
- 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的