Redis-狂神、慕课
-
定义:内存中的数据结构可持久化的存储系统,用作数据库、缓存、消息中间件。支持多类型数据结构(字符串、散列、列表、集合、有序集合、范围查询、索引半径查询),
内置了复制、LUA脚本、LRU驱动事件、事务和不同级别磁盘持久化,并通过Redis哨兵和自动分区提高可用性. -
基本知识
-
Redis五大基础 数据类型:List、set、Zset、Hash、String
-
单机、缓存+mysql+垂直拆分(读写分离)、分库分表+水平拆分+mysql集群
-
用户->路由网关->负载均衡(主备机)->服务器(123)->mysql(1-5) 独立的缓存服务器、移动信息服务器、Hadoop服务器、实时通信服务器
-
为什么用NoSQL?
用户的个人信息、社交网络、地理位置、用户产生数据、日志增长这些数据NoSQL处理。 -
3V3高 海量多样实时 高并发高可托高性能
-
NoSQL:不仅仅是数据、没有固定的查询语言、简直对存储列存储文档存储图形数据库、最终一致、
-
CAP定理和BASE异地多活、高性能、高可用、高可扩展性
-
NoSQL四大分类:新浪Redis 美团Redis+Tair 阿里百度Redis+Memcache(Memcache支持简单数据类型,需要客户端自己处理复杂对象)
-
Redis 默认16个库,select 0-15,默认0
NoSQL四大分类-类型 代表 特点 键值对数据库 Redis、Memecache 列存储数据库 Hbase、Cassandra HBase分布式文件系统 文档数据库 MongoDB、CouchDB json:MongoDB,基于分布式文件存储的数据库,处理大量的文档,介于关系型数据库和非关系数据库中 图形数据库 Neo4J、FlockDB 、infoGrid、infinite -
Redis作用:持久化存储,内存是断电即失、效率高可用于高速缓存、发布订阅系统、计时器计数器
-
Redis默认有16个数据库
-
redis单线程模型,在规避了cpu切换损耗的同时也能 保证数据顺序提交,不需要考虑数据一致性问题,单线程模型是因为文件事件处理器file event handler是单线程的,Redis底层采用了Epoll这款多路复用IO模型,非阻塞同步IO。
-
Memcache 是多线程模型通过cas(比较并交换java.util.concurrent包中无论是ReentrantLock内部的AQS,还是各种Atomic开头的原子类,内部都应用到了CAS)保证数据一致性
-
redis瓶颈是机器的内存和网络带宽,redis是C语言写的,官方提供数据为10,0000+QPS,不比key-value的Memcached差,对于内存系统说,如果没有上下文切换效率就是最高的。
-
集群种类
- 主从
- 哨兵
- 多主多从
-
-
安装Redis以及基础命令
- redis-server 目录下/redis.conf 通过指定 的配置文件启动服务
- ping 返回PONG
- redis-cli -p 6379
- set name age
- get name
- keys *
- shutdown -> exit
- ps -ef|grep redis 查看redis进程是否开启
- dbsize
flushall 清空全部数据 - exits key1
- incr/decr value
-
redis-benchmark是官方自带的性能测试工具
-
-
String字符串类型
user:{id}:{filed}巧妙设计 set user:1:name zhangyingqi user:2:age 24
mget user:1:nqme user:1:age
get db
getset db mongdb
get db
keys like*
keys *
SETINX age 18 不存在age这个KEY18会被设置进去
ttl age 30 设置age这个key过期时间为30S
StrLEN age 查看key的长度
incr age 累加key的值 ++
decr key 累减值 –
INCRBY key 数值 在基础上增加数值
DECRBY key 数值 累减
应用场景
共享⽤户Session:⽤户重新刷新⼀次界⾯,可能需要访问⼀下数据进⾏重新登录,或者访问⻚⾯缓存Cookie,但是可以利⽤Redis将⽤户的Session集中管理,在这种模式只需要保证Redis的⾼可⽤,每次⽤户Session的更新和获取都可以快速完成。⼤⼤提⾼效率
缓存功能
计数器 -
List
redis中list可以玩成栈、队列、阻塞队列
所有的list命令都是L
LPUSH list one
LRANGE list 0 -1 输出所有
LRANGE list 0 1
RPUSH list zyq
Lrange list 0 -1
LPOP RPOP
Lindex list 1 获取list某一个值通过下标
Llen list 返回列表长度
flush db
Lrem list 1 value 移除list集合中指定个数的value,精确匹配
ltrim list 1 2 截取指定的长度值,list只剩下截取的数
linsert list after one ten
使用场景:消息队列 栈 、相关推荐 -
Set
set中的值不能重复,Set是⽆序集合,会⾃动去重的
sadd myset hello
SMEMBERS myset 查看myset中所有值
scard myset 查看集合中的个数
SMEMBERS myset 查看集合中元素
srem myset “hello” 移除集合中的值
SRANDMEMBER myset 随机筛选出来一个值
spop myset 随机删除指定的key
sdiff set1 set2 差集 set中有set2没有
SINTER set1 set2 交集
SUNION set1 set2 并集
使用场景:微博共同好友、推荐 -
Hash
Map集合 key-Map
hset myhash field1 tom
hget myhash field1 返回tom
hmset myhash field1 hello field2 world
hgetall myhash
Hash本质上和String没有本质的区别,只是一个简单的key-value
hdel myhash field1 删除hash指定的字段对应的value也就消失
hlen myhash
HEXISTS myhash field1
hkeys myhash 只获得所有的key
hvals myhash 只获得所有的value
HINCRBY myhash filed1 1 自增
HEXISTS field1 tom 返回1存在0不存在
HDEL myhash field1 map中的删除属性
使用场景:适合存储经常变动的消息-用户信息、帖子点赞数评论数点击数、缓存近期热帖内存、用户历史行为 hash适合对象的存储 age name -
Zset有序集合 zset k score v
zadd myset 1 one
zrange myset 0 -1 withscores
zadd salary 1200 xiaohong
zadd salary 1500 xiaoming
zarangebyscore salary - inf +inf 升序排序
zarangebyscore salary - inf +inf whitscores
zrem salary xiaohong
zcard salary 获取有序集合个数
zcount myset 1 3 获取指定区间的成员数量
使用场景:热榜、收藏贴、贴关系、去重计数
-
-
三种特殊数据类型
+
geospatial 地理位置
china:key
geoadd china:city 经度 维度 地点名字
geopos china:city beijing chongqing 查看地点的经度纬度 获取当前定位一对坐标值
geodist china:city beijing shanghai 地点之间的直线距离 mi英里 ft英尺
georadius china:city 110 30 100km withdist|whithcoord 以点为半径查询城市带有纬度|直线距离
使用场景:我附近的人,获得所有附近的人的地址、定位
georadius china:city 110 30 100km withcoord count 2 查询指定数量
georadiusbymember china:city shanghai 400 km 查看以地点为中心距离多少的周边城市
geohash China:city beijing chongqing 返回一个或多个位置元素用hash表示 返回经纬度->字符串返回
zrange china:city 0 -1
+
Hyperloglogs
基数统计的算法
应用场景:网页的UV(一个人访问一个网站多次算一次)
PFadd myjihe1 a c b d e f
PFcount myjihe1
PFadd myjihe2 a e r t y
PFcount myjihe2
PFMerge myjihe3 myjihe1 myjihe2 将集合合并
+
Bitmaps
位存储,数据结构,都是操作二进制位来进行记录,只有01状态
位图是⽀持按 bit 位来存储信息,可以⽤来实现 布隆过滤器
setbit sign 0 1
setbit sign 1 0
getbit sign 1 查看某一天是否打卡
bitcount sign 0 1 在0-1区间统计打卡天数
365天=365bit 46字节,一字节等于8bit
+
Pipeline
可以批量执⾏⼀组指令,⼀次性返回全部结果,可以减少频繁的请求应答 -
事务
本质:一组命令的集合,一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行. 一次性、顺序性、排他性执行一系列命令.
Redis单条命令是保存原子性的,但是事务 不把证原子性。
Redis事务没有隔离级别的概念
开启事务(multi)->命令入队(… set k1 v1、 get k1、 set k3 v3、)->执行事务(exec执行|DISCAED放弃所有事务)
java错误:编译型异常、运行时异常(部分错误命令会抛出异常) -
监控->Watch
悲观锁:无论做什么都加锁
乐观锁:不上锁
set money 100
set out 0
watch money
multi
decrby money 10
incrby out 10
exec
测试多线程修改值,使用watch可以当做redis乐观锁操作
unwatch 解锁
如果发现事务执行失败,先解锁;获取最新的值,再次监视;比对监视的值是都发生变化,如果变化,执行失败
秒杀乐观锁使用watch -
Jedis
Jedis是Redis官方推荐的java连接开发工具,使用java操作Redis中间件
Jedis:采用直连,多个线程操作,不安全,避免不安全使用Jedis pool连接池 像BIO模式
lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据 像NIO模式
序列化:默认的序列化方式是JDK序列化,有可能是JSON序列化 -
持久化,在规定时间内执行多少次操作,则会持久化到文件 RDB AOF (RDB更适合做冷备,AOF更适合做热备)
redis是内存数据库,如果没有持久化,那么数据断电及失
如果只做缓存,不需要任何持久化,只希望 数据在服务器运行时存在 -
RDB-全量备份
Redis 会单独创建fork一个子进程进行持久化,会将数据写到一个临时文件中,待持久化过程结束,在用这个临时文件替换上次持久化好的文件,整个过程中,主进程是不进行IO操作的,确保了极高的性能,如果需要大规模数据恢复,对于数据恢复的完整性不是非常敏感,RDB比AOF方式更高效,RDB缺点是最后一次持久化后数据可能丢失.
默认是RDB,一般不需要修改这个配置.
触发机制:save规则满足、fushall、退出redis等情况下会自动触发RDB,备份自动生成dump.rdb
如何恢复rdb文件:rdb文件 放在redis启动目录即可
优点:适合大数据恢复、对数据的完整性要求不高
缺点:需要一定时间间隔进程操作,redis意外死机,最后一次数据没有、fork进程占用内容空间
主从复制中,rdb就是备用,在从机上面 -
AOF-增量定时
将所有命令记录下来,history恢复时候会将这个文件全部执行一遍
配置文件配置:
[appendfsync always]每次修改都会sync消耗性能
[appendfsync everysec]每秒执行一次sync,可能会丢失数据
[appendfsync no]不执行sync,这个时候操作系统自己同步数据,速度最快
Redis 会单独创建fork一个子进程,以日志的形式来记录每个写操作,将执行过得所有指令记录下来,只需追加文件不可以修改文件(appendOnly.aof),redis启动之初会读取改文件重新构建数据。
redis提供工具检查aof文件是否有错位redis-check-aof —fix appendOnly.aof
优点:每一次修改都同步,文件完整性好,从不同步效率最高,每秒同步数据,可能会丢失1s数据
缺点:RDB恢复数据比AOF快,AOF是IO操作,慢 -
Redis发布订阅
通信、队列
Redis发布订阅pub|sub是一种消息通信模式
Redis客户端可以订阅任意数据的频道
消息发布者(redis cli)->发布消息->[队列redis server]{消息订阅者去抢 redis cli}
Redis是C语言实现的,通过 PUBLISH SUBSCRIBE PSUBSCRIBE 实现发布和订阅功能 -
主从复制
Master|Slave
单个redis并发量上限是5-6W
主从复制,读写分离,80%情况下都市进行读操作,减缓服务器压力,一主二从
配置环境单机多集群:
复制配置文件修改信息[端口、log文件名、pid名字、dump.rdb名字]、启动
全量复制:salve服务接口道数据库文件数据,将其存盘加载到内存中
增量复制:master继续讲收集到新的传递给salve
原理:选主的策略简单来说有三个:slave 的 priority 设置的越低,优先级越⾼;同等情况下,slave 复制的数据越多优先级越⾼;相同的条件下runid 越⼩越容易被选中;
-
搭建主从复制(读写分离)
让这个master机器去写,数据同步给别的slave机器,他们都拿去读,分发掉⼤量的请求
- 步骤
191主::info replication
192从1:vim redis.conf
192从1:replicaof masterip masterport
192从1:masterauth master-password
192从1:/etc/init.d/redis_init_script stop 然后start
192从1:redis-cli
193从2:cd /usr/local/redis/working/
193从2:rm dump.rdb appendonly.aof
193从2:vim redis.conf
193从2:replicaof 192.168.1.191 6379
193从2:masterauth master-password
193从2:/etc/init.d/redis_init_script stop 然后start
193从2:redis-cli
- 步骤
-
无磁盘化复制原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传步骤: 实验阶段不能使用在生产环境
1、vim redis.conf
2、repl-diskless-sync yes -
哨兵模式Sentinel
if master kill ->哨兵模式
选举新的master组成新的主从复制,多个哨兵
cp sentinel.conf /usr/local/redis/ redis.conf同目录下
哨兵模式核心配置文件sentinel.conf [sentinel monitor 被监控名称 host 6379 1(哨兵数)]
sentinel auth-pass master-name password
sentinel down-after-milliseconds master-name 30s
sentinel parallel-syncs master-name 并行同步的数量
sentinel failover-timeout master-name 18s
启动[redis-sentinel config/sentinel.conf]
优点:哨兵集群,基础主从复制,所有主从复制优点均有、主从可以切换,故障可以转移,系统可用性好、哨兵模式自动,健壮
缺点:redis不好在线扩容,集群容量达到上限,麻烦、哨兵配置麻烦选择性多
图解哨兵
redis-cli -p 端口号 连接哨兵
master-name下的master信息检查 sentinel master master-name
master-name下的slaves信息检查 sentinel slaves master-name
master-name下的哨兵节点信息检查 sentinel sentinels master-name
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 -
Redis缓存穿透和雪崩
缓存穿透(查不到):缓存 没有,直接访问数据库也没有 解决方法:缓存层加缓存null对象、布隆过滤器
缓存击穿(查太多次):是指一个key非常热点,并发访问一个点,key失效瞬间,持续就穿破缓存,直接请求数据库,写缓存,会导致数据库瞬间压力过大 解决方法:设置热点数据永不过期、加互斥锁(使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有锁的权限,这种方式将高并发压力转移到分布式锁,因此分布式锁考验很大)
缓存雪崩:指某段时间内,缓存集中过期失效,Redis宕机 解决办法:redis高可用搭建集群异地多活、限流降级springCloud、数据预热(在正式部署之前,可能的数据预先访问一遍,大量数据加载到缓存中,将发生大量访问前手动触发加载缓存不同的key,设置过期时间,让缓存失效的时间点尽量均匀)类型 含义 解决方案 代码 缓存穿透 查询的key在redis中不存在,对应的Id在数据库也不存在,此时被非法用户进行攻击,大量的请求会直接打在db上,造成宕机,从而影响整个系统 把空的数据也川村起来比如空字符串,空对象,空数组,空集合 缓存穿透 查询的key在redis中不存在,对应的Id在数据库也不存在,此时被非法用户进行攻击,大量的请求会直接打在db上,造成宕机,从而影响整个系统 布隆过滤器 利用高效的数据结构和算法快速判断出key是否存在数据库中,不存在return,存在查询DB刷新kv再return 缓存击穿 缓存击穿不同的是缓存击穿是指⼀个Key⾮常热点,在不停的扛着⼤并发,⼤并发集中对这⼀个点进⾏访问,当这个Key在失效的瞬间,持续的⼤并发就穿破缓存,直接请求数据库,就像在⼀个完好⽆损的桶上凿开了⼀个洞 在接⼝层增加校验,⽐如⽤户鉴权校验,参数做校验,不合法的参数直接代码Return,⽐如:id 做基础校验,id <=0的直接拦截等 缓存雪崩 指某段时间内,缓存集中过期失效,Redis宕机,请求大量请求DB,DB宕机(如果所有⾸⻚的Key失效时间都是12⼩时,中午12点刷新的,我零点有个秒杀活动⼤量⽤户涌⼊,假设当时每秒6000个请求,本来缓存在可以扛住每秒5000个请求,但是缓存当时所有的Key都失效了,此时1秒6000个请求全部落数据库,数据库必然扛不住,它会报⼀下警,真实情况可能DBA都没反应过来就直接挂了,此时,如果没⽤什么特别的⽅案来处理这个故障,BA很着急,重启数据库,但是数据库⽴⻢⼜被新的流量给打死了) 设置永不过期、过期时间错开(在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同⼀时间⼤⾯积失效)、多缓存结合(阿里百度Redis+Memcache过期时间比redis长一点,先查询redis在查询Memcache,最后查询DB,相当于进行二级缓冲、购买第三方Redis例如->阿里云) 过期时间错开:setRedis(Key,value,time + Math.random() * 10000); -
阻塞与非阻塞
-
缓存过期机制
1、定期删除
2、vim redis.conf -> hz 一般设置10
3、惰性删除(过期的key请求 ,检测是否过期,删除)不怎么占用CPU但是占用内存
4、内存淘汰管理机制,Memory management 、maxmemory
内存淘汰策略:内存淘汰策略 含义 noeviction 不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,这种策略下可以保证数据不丢失,它也是 Redis 默认的内存淘汰策略 allkeys-lru 淘汰整个键值中最久未使用的键值,这也就是我们常说的LRU算法 allkeys-random 随机淘汰任意键值 volatile-lru 淘汰所有设置了过期时间的键值中最久未使用的键值 volatile-random 随机淘汰设置了过期时间的任意键值 volatile-ttl 优先淘汰设置了过期时间中更早过期的键值 -
- slot槽节点一共有16384,用于存储数据 hash(key)%16384=地址,slot是在master上的
-
- multiGet批量查询优化
- redis的管道功能,nginx->keepAlive、redis->pipeline
-
分布式锁
- 多个系统同时操作(并发)Redis带来的数据问题?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t8UYy8LN-1650008168391)(img_13.png)]- 每个系统通过
Zookeeper获取分布式锁,确保同⼀时间,只能有⼀个系统实例在操作某个Key,别⼈都不允许读和写。
- 每个系统通过
- setnx指令
setnx aobing expire aobing del aobing
- 从DB查出来的数据要写入缓存,数据在Mysql必须存储时间戳,每次写之前都需要比较时间戳,避免旧数据覆盖新数据
- redis分布式锁
- 先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放
- 如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
- set 指令有非常复杂的参数,这个应该是可以同时 把 setnx 和 expire 合成一条指令来用的!
#使用方法
1、后台系统,某些数据发生改变,就可以删除缓存,重置,可以选择定时重置
2、在缓存查询,存在即返回,不存在查询并存储到redis
- 多个系统同时操作(并发)Redis带来的数据问题?
#面试题
-
什么是redis
- redis是内存中数据结构可持久化的存储系统,用作数据库缓存消息中间件,支持多种数据结构内置了复制、LUA脚本、驱动事件、事务和磁盘持久化。
-
redis数据类型
- 五种基础String、Hash、List、Set、SortedSet
- 四种其他HyperLogLog、Geo、Bitmaps 、PUB/SUB
-
redis使用的好处
- 性能快
-
速度快
-
多路IO复用模型是非阻塞
-
redis是采用基于内存的采用的是单进程单线程模型的kv数据库,官方提供数据是10W的QPS(关系型数据库与redis本质的区别)
-
完全基于内存,速度快,数据查找类似于HashMapc查找和操作的时间复杂度o(1)
-
单线程:避免了上下文切换、竞争条件、不消耗CPU、不用考虑锁的问题和性能
-
- 缓存减少数据库压力
- 丰富的数据类型
- 原子性:Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行.单个操作是原子性的.多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来
- 丰富的特性:PUB/SUB、管道、过期时间等
- 性能快
-
redis是单线程的为什么怎么高效?
- Redis 采⽤单线程模式处理请求。这样做的原因有 2 个:⼀个是因为采⽤了⾮阻塞的异步事件处理机制;另⼀个是缓存数据都是内存操作 IO 时间不会太⻓,单线程可以避免线程上下⽂切换产⽣的代价
-
持久化机制,各自优缺点
- RDB是全量持久化(Redis 会单独创建fork一个子进程进行持久化,子进程会cow,将数据写到一个临时文件中,父进程提供读写服务,待持久化过程结束,在用这个临时文件替换上次持久化好的文件,整个过程中,主进程是不进行IO操作的,确保了极高的性能)
- AOF是定时增量持久化(将所有命令记录下来,history恢复时候会将这个文件全部执行一遍)
-
redis常见性能问题和解决方案
- master最好不好写内存快照,如果master写内存快照使用save命令会堵塞主线程的工作,当快照比较大的时候对性能影响很大,会简短性暂停服务
- 如果数据重要,莫个slave开启AOF备份数据,策略设置每秒同步机制
- 为了主从复制的速度和连接性的稳定性,主从节点最好在同一个局域网
- 避免在压力大的主库增加从库
- 主从复制不要用图表结构,使用单向链表结构会稳定master->salve1->salve2,此结构方便解决单点故障问题,实现了slave对master的替换,如果master宕机,可以立即启用slave1
-
redis过期的删除策略
- 被动删除、主动删除
-
回收策略
内存淘汰策略 含义 noeviction 不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,这种策略下可以保证数据不丢失,它也是 Redis 默认的内存淘汰策略 allkeys-lru 淘汰整个键值中最久未使用的键值,这也就是我们常说的LRU算法 allkeys-random 随机淘汰任意键值 volatile-lru 淘汰所有设置了过期时间的键值中最久未使用的键值 volatile-random 随机淘汰设置了过期时间的任意键值 volatile-ttl 优先淘汰设置了过期时间中更早过期的键值 -
为什么把数据放到内存中
-
同步机制
- redis可以使用主从同步、从从同步。启动⼀台slave的时候,他会发送⼀个psync命令给master,如果是这个slave第⼀次连接到master, 他会触发⼀个全量复制。master就会启动⼀个线程,⽣成RDB快照,还会把新的写请求都缓存在内存 中,RDB⽂件⽣成后,master会将这个RDB发送给slave的,slave拿到之后做的第⼀件事情就是写进本 地的磁盘,然后加载进内存,然后master会把内存⾥⾯缓存的那些新命名都发给slave。复制节点进行重放就完成了同步过程,后续增量数据通过AOF日志同步即可
-
pipeline好处
- 可以将多次io往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性,使用redis-benchmark进行压测的时候可以发现redis的QPS峰值重要因素是pipeline批次指令的数目
-
集群原理
- Sentinel高可用,在master宕机时会自动slave提升为master,继续提供服务
- Cluster高拓展,在单个redis内存不够,使用Cluster进行分片存储
-
什么情况下会导致整个集群不可用
- 有ABC三个节点的集群,在没有复制模型的情况下,如果节点B失败了那么整个集群就以为缺少B对应的范围槽节点而不可用
-
redis支持的java客户端有那些
- Redisson(官方推荐)、Jedis、Lettuce
-
jedis、redisson优缺点
jedis redisson Jedis 是 Redis 的 Java 实现的客户端 Redisson 实现了分布式和可扩展的 Java 数据结构 API 提供了比较全面的 Redis 命令的支持 功能较为简单,不支持 字符串操作,不支持排序、事务、管道、 分区等 Redis 特性。 对于分布式,功能复杂不如 jedis Redisson 的宗旨是促进使用者对 Redis 的关注分离,让使用者能够将精 力更集中地放 在处理业务逻辑上 -
哈希槽
- Redis没有使用一致性hash,而是引入了哈希槽的概念,redis集群有16384个哈希槽,每个key通过校验对这个1.6W个取模来决定放置那个槽中,集群的每个节点负责一部分hash槽
-
redis主从复制模型
- 为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用, 所以集群使用了主从复制模型,每个节点都会有 N-1 个复制品。例如常见的三主三从,如果没有复制模型会导致整个集群不可用
-
redis如何设置密码及验证密码
- 设置密码:config set requirepass 123456
- 授权密码:auth 123456
-
redis集群写操作丢失
- Redis 并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
-
集群如何复制的
- 异步复制
-
集群最大节点个数
- 16384
-
集群如何选择数据库
- Redis集群目前无法做数据库选择,默认在0数据库。
-
redis连通性
- ping
-
redis事务
- 事务是一个单独的隔离操作,事务中的所有命令都会序列化,按顺序的执行,事务在执行过程中,不会被其他客户端发送的命令请求打断
- 事务是一个原子操作,事务中的命令要么全部执行,要么全部都不执行
- LUA
- 管道
- 锁
-
事务命令
- multi、exec、discard、watch
-
key的过期时间和永久有效设置
- Expire KEY_NAME TIME_IN_SECONDS
- PERSIST KEY_NAME
-
内存如何优化
- 在配置文件配置
- 尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。
-
回收进程如何工作
- 一个客户端运行了新的命令,例如添加了新的数据,redis检查内存使用情况,如果大于MAX限制,则根据设定好的策略回收,如果一个命令的结果导致大量内存被使用(例如很大 的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
-
降低redis内存使用情况
- 好好利用 Hash,list,sorted、set,等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。
-
redis内存使用完后会发生什么
- 配置淘汰机制,达到设置上限后,会冲刷掉旧的内容,进行存储,如果没有设置淘汰机制,达到上限写命令会返回error
-
redis实例最多存放keys,string list set sorted set最多存放多少数据
- redis每个实例(库)理论可以存放2的32次幂个keys也就是40亿,Redis的存储极限是系统中的可用内存值。实践中存放2.5亿
- 任何hash、list、set、和sorted set都可以放2的32次方个keys(40亿)个元素
- string(512M),一个key和value最大是512M
-
BD2kw数据,redis20w如何保证热点数据
- 可以使用 Redis 的内存淘汰策略来实现,可以使用allkeys-lru淘汰策略,该淘汰策略是从 Redis 的数据中挑选最近最少使用的数据删除,这样频繁被访问的数据就可以保留下来了。
- 了解下数据存储内存占用,例如1个中文占2个字节,假如1条数据有100个中文,则1条数据占200字节,20w数据 乘以 200字节 等于 4000 字节(大概等于38M);所以要保证能存20w数据,Redis 需要38M的内存
-
保证缓存和数据库一致性方案
四种同步策略 先更新缓存后更新数据库 先更新数据库再更新缓存 先删除缓存,在更新数据库 先更新数据再删除缓存 -
假如 Redis 里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?
- 使用 keys 指令可以扫出指定模式的 key 列表
- 如果这个redis正在给线上的业务提供服务,那使用keys指令会keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复,因为redis 的单线程的
- 可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长
-
redis最适合的场景
-
秒杀库存扣减
-
app首页访问流量高峰
-
与Memcache区别
名称 特点 Redis 单核;单线程非阻塞同步IO; 有集群模式,主从模式;可持久化提供高可用服务;多数据结构 Memcache 多核;多线非阻塞程异步IO ;无原生集群需要客户端实现往集群分片写入数据;KV存储;内存存储,没有持久化和主从同步功能;key小于250B,value小于1MB,过期时间小于30day:失效是延迟失效;使用LRU进行数据剔除
-
Redis进阶
后期补充Redis Module(BloomFilter,RedisSearch,Redis-ML)
-
Tair的多线程实现更加优雅。如下图
多线程种类 职责 Main Thread 负责客户端连接建立 IO Thread 负责请求读取、响应发送、命令解析等(读取用户的请求并进行解析,之后将解析结果以命令的形式放在队列中发送给Worker Thread处理) Worker Thread 线程专门用于事件处理(Worker Thread将命令处理完成后生成响应,通过另一条队列发送给IO Thread)
- 为了提高线程的并行度,IO Thread和Worker Thread之间采用无锁队列 和管道 进行数据交换,整体性能会更好。