Redis基本知识

应用场景:

缓存数据库,

消息队列(发布订阅)

缓存数据同步方式:

双读双写:应用面对缓存与数据库;读时先读缓存,没有数据时再读数据库,并将读取到的数据更新到缓存;写时先写数据库再写缓存

异步更新:加一个更新工具,定时将数据库中的数据写入缓存,应用只读缓存,只写数据库;

串联模式:应用只面对缓存,缓存作为一个代理;应用只读写缓存,缓存读写数据库;

数据结构:string, list, hash, set, zset

string:

存储:字符串、整型(相当于long)、浮点型(双精度)

结构:int/SDS(simple dynamic string, 可以根据要存储的string的长度,自动分配指定大小规模的内存(默认2^8-1),可以节省内存占用)

list:

存储:很多string

特性:有序性、不唯一

结构:linkedlist(双向循环列表;访问稍慢插入删除快,内存占用多)、

ziplist(压缩列表,内存占用连续,可以认为是数组;访问快插入删除慢,内存占用少)、

quicklist(ziplist与linkedlist的组合)

hash:

存储:Java中的对象,对应与数据库表中的一行

(注:value类型只能为string,也就是说hash结构不能够嵌套其他结构!)

结构:ziplist(数据量少时)、hashmap(散列表结构)

set:

存储:很多string,*value为null的hash*

特性:无序性、唯一性

结构:intset(数组结构,只包括整型的时候使用inset)、hashmap(value为null)

使用:标签

zset:

存储:很多string,*key为score的hash*

特性:唯一性,有序性

结构:ziplist(数据量少时)、skiplist + hashmap(key为score)

使用:排名

内部原理:

1.缓存过期策略:

expire key seconds

缓存的过期主要通过 定期删除 + 惰性删除

定期删除:周期性地、随机地扫描,并使一些key过期

惰性删除:当key被访问的时候,才使相应的key过期

2.pub/sub:

通过channel实现pub/sub,channel的名称支持正则/全称,

与消息中间件的pub/sub的不同:不支持多协议,不支持持久化,不支持回滚,可靠性不高

3.持久化:

使用场景:当把redis作为主数据库、避免redis重启导致的缓存大量击穿

持久化方式:RDB、AOF

RDB:当满足条件时,fork一个子进程,将当前数据快照到文件,每次都全量快照;

     优缺点:数据恢复速度快;可能会导致数据丢失;

     条件:配置save seconds changes、用户主动执行save(阻塞所有客户端请求),bgsave(不会阻塞客户端请求)、flushall、复制(主从)

AOF:append only file,实时记录用户的事务性操作命令;

     优缺点:可以避免数据丢失;影响性能;

     指令压缩:避免aof文件过大;fork一个子进程,将当前内存中的数据生成指令记录在aof中,俗称“指令压缩”

4.内存淘汰机制:

物理内存的有限,导致涉及到内存的中间件必须要考虑限制自己的内存使用,考虑内存回收策略,比如redis,jvm

淘汰策略:

     noeviction(默认),无内存可用时,报错

     allkeys-lru:面向所有的key,最近最少使用的key被淘汰(LRU算法,类比LinkedHashMap)

     allkeys-random:面向所有的key,随机淘汰

   Volatile-lru:面向设置了过期时间的key,最近最少使用的key被淘汰

   Volatile-ttl:面向设置了过期时间的key,快要达到过期的时间的key被淘汰

   volatile-random:面向设置了过期时间的key,随机淘汰

5.单线程为什么可以处理高并发?

使用多线程的原因是为了更多的使用CPU资源,而redis的瓶颈并不在于CPU,而在于内存和网络,所以选择单线程

IO多路复用机制:虽然是单线程,但是通过IO多路复用,可以使用单线程来处理多个网络请求

6.lua脚本:

原子性问题:

redis虽然是单一线程的,但是仍然会存在线程安全问题,当然,这个线程安全问题不是来源于Redis服务器内部,

而是Redis作为数据服务器,是提供给多个客户端使用的,多个客户端的操作就相当于同一个进程下的多个线程,

如果多个客户端之间没有做好数据的同步策略,就会产生数据不一致的问题。

多个客户端的命令之间没有做请求同步,导致实际执行顺序可能会不一致,最终的结果也就无法满足原子性了

效率问题:

redis本身的吞吐量是非常高的,因为它首先是基于内存的数据库。在实际使用过程中,有一个非常重要的因素影响redis的吞吐量,那就是网络。

我们在使用redis实现某些特定功能的时候,很可能需要多个命令或者多个数据类型的交互才能完成,那么这种多次网络请求对性能影响比较大。

当然redis也做了一些优化,比如提供了pipeline管道操作,但是它有一定的局限性,就是执行的多个命令和响应之间是不存在相互依赖关系的。

所以我们需要一种机制能够编写一些具有业务逻辑的命令,减少网络请求

特点:

减少网络开销:在Lua脚本中可以把多个命令放在同一个脚本中运行

原子操作:redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。换句话说,编写脚本的过程中无需担心会出现竞态条件

复用性:客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑

使用:

lua是一种脚本语言,redis支持lua脚本在redis-cli上执行,lua脚本语言有针对redis的库;

eval “lua脚本”:执行lua脚本(redis.call(...))

evalsha “lua脚本摘要”:通过脚本摘要执行lua脚本,避免每次传输lua脚本,脚本体积大导致的网络传输慢的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值