redis-基础

1、redis简述

redis 是一门C语音开发的,redis开发者,一开始的本意是作用消息队列,后面随着IT圈的迅速发展,redis不满足诉求;最后开发成k/v形式的内存存储的工具

特性:速度快、单进程单线程、支持集群、持久化

为啥快?

a)、操作内存

b)、单进程单线程,不存在资源竞争,上下文切换

c)、多路复用,多路-->网络连接 复用--> 复用的是一个线程

2、redis支持类型

前言

所有key的类型是redis内部定义sds string类型,长度最大是512M,所有value的类型都是redisObject

但是redisObject里面又细分,这里后面不同类型阐述。

1、string

操作指令:set key value get key

外部类型 --> string

内部类型 --> 如下

可通过object encoding key或者debug object key,查看value信息

a)、内容是数字: < 44 --> int ; >44 -->raw

b)、内容非数字:< 44length --> empstr ; > 44 --> raw

c)、为什么是44length?

内存分配器(2/4/8/16/32/64 字节)

sds --> 3字节

redisObject --> 16字节

也就是19个字节,至少要分配内存32字节下来, 这里就不在深入进去,在深入我不懂ing,尬了尬了

2、hash

操作指令: hset hget hmgetAll不罗列

外部类型 --> 哈希表 key :: field :: value

内部类型 --> 如下

a)、hashtable哈表

dict外层 --> 字典数据结构,两个dictht表ht[0],ht[1],一个使用 一个为空,方便扩容

dictht -- > 指向dictentry数组的指针

dictentry -> 数组+链表形式存放

b)、ziplist

使用条件 --> 保存field数量小于512; 所有的field和value的字符串长度都小于64字节

经过特殊编码,连续的内存块组成双向链表, 不存指针的地址,存储的上节点长度和当前节点长度

c)、扩容 --> 元素的个数 / 数组的长度 > 5 触发扩容

触发扩容 --> 在空的dictht表里创建原本大小的2的幂次方, 重新rehash分配到新表 , 释放ht[0]的空间,

将ht[1]这张表改为ht[0],创建新的ht[1],为下次做准备

3、set

操作指令: sadd sget

存储类型: intset hashtable

4 、list

特性:存储有序的字符串(从左往右), 元素可重复

数据类型: quicklist -- > a) head 记录头节点

b) tail 记录尾节点

c) count 所有ziplist的元素个数

d) len 双向链表的长度

e) queicklistNode 双向链表 --> pre 上节点 tail 下节点 ziplist 压缩列表

5、zset

特性: 存储有序元素,不允许重复元素,按照score从小到大排序,score相同按照 ASCII码排序

数据模型 : ziplist -- > 元素数量小于128,所有长度小于64字节

skiplist + dict -- > skiplist跳表 -- >

6、BitMaps

a)、存储类型: 字符串存储

b)、数据模型 : 一个字节八位二进制位组成

7、Hyperloglog

未了解

8、Geospatial

存放经纬度,计算经纬度距离

3、redis内存淘汰、过期策略

a)、过期策略:redis采用定时清除和惰性清除,

定时清除 -> 定时清除ttl过期的key,扫描部分,造成可能大量已经ttl过期的key未删除

惰性清除 --> 客户端get的时候,查看是否ttl过期,过期就删除

大量ttl过期key未删除,会导致内存不够用,要保证redis是可用状态,就出了内存淘汰,过期

b)、内存淘汰 --> 如上过期数据还是可能出现内存不过用,所以淘汰一些数据来保证可用性

淘汰策略 --> lru 最少使用

--> lfu 最少使用(评率)

--> random 随机

--> volatile 设置了过期时间

--> allKey 全部key ,不看是否有设置ttl

--> noeviction 不做任务淘汰策略,直接报错

组合8种使用 --> volatile-lru --> 设置了ttl,最少使用, 例:A很少用,redis准备删除A了,客户端突然使用下A,

一下就热点数据了,不公平吧。

volatile-lfu --> 在volatile-lru基础下,增加次数,具体实现,出门左转百度下,这里不做阐述实现

volatile-ttl --> 快要过期的

volatile-random --> 随机删除设置时间的

不管你有没有设置时间

allKey-lru --> 挑选最近最少使用的数据淘汰

allKey-lfu --> 挑选最近最少次数使用的数据淘汰

allKey-random --> 随机挑选使用的数据淘汰

no-noeviction 不做淘汰,oom出去。不能插入,但是可以get操作

c)、建议使用: volatile-lru 保证正常服务的情况下,优先删除最近最少使用的key

4、redis持久化

1、aof

执行一次指令就保存

持久策略: no --> 不执行fsync,由操作系统保证数据同步到磁盘, 速度快,但是不安全

always --> set a 123, 先更新到redis缓存,在刷新到aof文件中

everysec(推荐) --> 先把执行命令写入到buffer中,在以每秒执行一次fsync, 效率可以保证,但可能会丢失一秒的数据

优点:提供丰富的同步策略

缺点:aof文件更大,不合适做数据备份

2、rdb

生成快照:在conf配置的x秒内达到ykey就会生成快照

正常关机也会生成快照

指令flushall会生成快照

指令save会生成快照,但是这个是阻塞式的,执行这个指令,其他不能执行

执行bgsave会生成快照,fork一个子进程,共享父类内存,不阻塞

优点: 生成的文件会比aof文件小,适合做数据备份,文件小,更合适恢复数据

缺点: 会丢失数据

aof,rdb的混合

Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行, 在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。

在同时开启rdb和aof情况下
set a 123
set b 123
set c 123
aof每秒设置到aof文件中
同时也快快照到rdb文件中,在二次快照后,会清空aof文件。

3、方案比较

1、如果能忍受一小段时间的数据丢失,选择rdb,如果不能,就选择aof

2、(推荐)不要单独设置一种持久化机制,两种一起用,AOF比RDB的数据要完整

4、redis重启加载文件顺序

1、如果开启了aof,优先查看是否有aof文件,如果有,则加载aof文件,启动redis。

2、如果开启了aof,无aof文件,则查看是否有rdb文件,如果有,则加载rdb文件,启动redis。

3、如果开启了aof,无aof文件,则查看是否有rdb文件,如果无,启动redis。

4、如果无开启aof,则查看是否有rdb文件,如果有,则加载rdb文件,启动redis。

5、如果无开启aof,则查看是否有rdb文件,如果无,则加载rdb文件,启动redis。

3、redis集群

后面在写一篇文档关于集群

4、redis应用场景

1、string类型适合场景 --> 缓存热点时间

--> 分布式session登录

--> 分布式锁

--> 计数器incr/decr

--> 限流?

2、hash类型适合场景 --> 跟string差不多,但是field无法设置时间

3、list类型适合场景 --> 热点数据列表 (文章)

--> 消息队列

4、set类型适合场景 --> 抽奖(不能重复)

--> 点赞/打卡/签到

--> 关系模型

--> 交集/并集/差集操作

5、zset类型适合场景 --> 热搜/主题

6、bitmap类型适合场景 --> 用户访问统计

--> 在线用户统计

--> 用户签到

--> 与、或、异或、非运算

7、Hyperloglog类型适合场景 --> 不太精确的基数统计

--> 统计网站UV

--> 日活、月活

8、Geospatial类型适合场景 --> 经纬度操作,距离比较

5、redis高级特性

1、事物

特点: 把一组指令一起(进入队列顺序)执行

不会受到其他命令干扰,一组命令set 11 22 set 22 33 在开启事务后,如果有另外的命令在操作11,22 key的命令。那么事务会取消了。 事物是不能嵌套的

用法: multi开启命令

exec 执行事务 --> 只能捕捉错误语法的指令,事物不会执行成功

--> 没有语法错误,但是执行过程中,指令错误,已执行的指令执行成功,错误的且未执行的不成功

discard 取消事务

watch 监视 --> 防止事务过程中某个key的值被其他客户端修改,并且取消事务

--> CAS乐观锁行为

2、发布订阅
3、lua

特点:批量执行指令

原子性 --> 排斥其他客户端指令 (排他)

脚本写入文件,集合复用

应用场景: 限流

秒杀

好处:
①高效,在服务器上执行,节省了网络传输开销等,特别lua脚本,执行多个脚本,好处就体现出 来了。

②原子性;一个业务需要多个指令完成,lua脚本比较好的选择

缺点:那就是如果你lua过于复杂,假如在里面取bigkey操作了,获取取值过大等等,就会阻塞;

执行时间过长;

如果配置主从,有两种同步方式:

1、脚本复制:意思很明确,就是在从节点也执行一边,在5.0后,就移除了,默认就是效果复制。

2、效果复制:就是把结果同步。

指令:

1、加载lua脚本到redis服务中

./redis-cli -a 密码 -p 端口 script load '$(cat 1.lua)';

返回一个sha1的值

通过evelsha sha1的值

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值