当前位置: 首页 > news >正文

Redis原理,命令,协议以及异步方式

Redis 是 Remote Dictionary Service 的简称;也是远程字典服务;是一个开源的、基于内存的高性能键值存储系统,支持多种数据结构(如字符串、哈希、列表、集合、有序集合等)。常用于缓存、消息队列、实时分析等场景。Redis 是内存数据库,KV 数据库,数据结构数据库;

内存数据库指的是redis存储在内存中不像MySQL一样存在磁盘中。

KV数据库指的是整体结构是以key-value的结构存储

数据结构数据库指的是value可以是5种数据结构:string,list,hash,set,zset

具体应用

记录朋友圈点赞数、评论数和点击数(hash)

记录朋友圈说说列表(排序),便于快速显示朋友圈(list)

记录文章的标题、摘要、作者和封面,用于列表页展示(hash)

记录朋友圈的点赞用户ID列表(list),评论ID列表(list),用于显示和去重计数(zset)

缓存热点数据,减少数据库压力(hash)

如果朋友圈说说 ID 是整数 id,可使用 redis 来分配朋友圈说说 id(计数器)(string)

通过集合(set)的交并差集运算来实现记录好友关系(set) 游戏业务中,每局战绩存储(list)

具体结构图

value类型

string

字符数组,该字符串是动态字符串 raw,字符串长度小于1M 时,加倍扩容;超过 1M 每次只多扩 1M;字符串最大长度为 512M;

注意:redis 字符串是二进制安全字符串;可以存储图片,二进制协议等二进制数据;但一半不存储,因为redis是内存数据库,存储这些很不合适

基础命令

# 设置 key 的 value 值
SET key val# 获取 key 的 valueGET key# 执行原子加一的操作
INCR key# 执行原子加一个整数的操作
INCRBY key increment# 执行原子减一的操作
DECR key# 执行原子减一个整数的操作
DECRBY key decrement# 如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做
# set Not eXist   ok 这个命令是否执行了  0,1 是不是操作结果是不是成功
SETNX key value# 删除 key val 键值对
DEL key# 设置或者清空key的value(字符串)在offset处的bit值。 setbit embstr raw  int# 动态字符串 能够节约内存
SETBIT key offset value# 返回key对应的string在offset处的bit值
GETBIT key offset# 统计字符串被设置为1的bit数.BITCOUNT key

累加器

# 统计阅读数 累计加1incr reads# 累计加100incrby reads 100

分布式锁

 # 加锁   加锁 和 解析  redis 实现是 非公平锁     ectd zk  用来实现公平锁
# 阻塞等待   阻塞连接的方式
# 介绍简单的原理: 事务
setnx lock 1   # 不存在才能设置 定义加锁行为  占用锁  
setnx lock uuid  # expire 30 过期
set lock uuid nx ex 30# 释放锁
del lockif (get(lock) == uuid)del(lock);

list

双向链表实现,列表首尾操作(删除和增加)时间复杂度O(1);查找中间元素时间复杂度为 O(n)

基础命令

 # 从队列的左侧入队一个或多个元素
LPUSH key value [value ...]# 从队列的左侧弹出一个元素
LPOP key# 从队列的右侧入队一个或多个元素
RPUSH key value [value ...]
# 从队列的右侧弹出一个元素
RPOP key                
# 返回从队列的 start 和 end 之间的元素  0, 1 2  负索引
LRANGE key start end# 从存于 key 的列表里移除前 count 次出现的值为 value 的元素
# list 没有去重功能    hash set zsetLREM key count value# 它是 RPOP 的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候阻塞连接
BRPOP key timeout  # 超时时间 + 延时队列

应用

我们可以利用链表同时只进行一边的出和进来实现不同的结构

栈(先进后出)
 LPUSH + LPOP# 或者
RPUSH + RPOP
队列(先进先出)
 LPUSH + RPOP# 或者
RPUSH + LPOP
阻塞队列
 LPUSH + BRPOP# 或者
RPUSH + BLPOP

hash

散列表,在很多高级语言当中包含这种数据结构;c++ unordered_map 通过 key 快速索引 value;

基础命令

#  获取 key 对应 hash 中的 field 对应的值
HGET key field#  设置 key 对应 hash 中的 field 对应的值
HSET key field value#  设置多个hash键值对
HMSET key field1 value1 field2 value2 ... fieldn valuen#  获取多个field的值
HMGET key field1 field2 ... fieldn#  给 key 对应 hash 中的 field 对应的值加一个整数值
HINCRBY key field increment#  获取 key 对应的 hash 有多少个键值对
HLEN key#  删除 key 对应的 hash 的键值对,该键为fieldHDEL key field

set

集合;用来存储唯一性字段,不要求有序;

基础命令

 # 添加一个或多个指定的member元素到集合的 key中
SADD key member [member ...]# 计算集合元素个数
SCARD key# SMEMBERS keySMEMBERS key# 返回成员 member 是否是存储的集合 key的成员
SISMEMBER key member# 随机返回key集合中的一个或者多个元素,不删除这些元素
SRANDMEMBER key [count]# 从存储在key的集合中移除并返回一个或多个随机元素
SPOP key [count]# 返回一个集合与给定集合的差集的元素
SDIFF key [key ...]# 返回指定所有的集合的成员的交集
SINTER key [key ...]# 返回给定的多个集合的并集中的所有成员
SUNION key [key ...]

zset

有序集合;用来实现排行榜;它是一个有序唯一;

基础命令

# 添加到键为key有序集合(sorted set)里面
ZADD key [NX|XX] [CH] [INCR] score member [score member ...] 
# 从键为key有序集合中删除 member 的键值对
ZREM key member [member ...] 
# 返回有序集key中,成员member的score值
ZSCORE key member 
# 为有序集key的成员member的score值加上增量incrementZINCRBY key increment member 
# 返回key的有序集元素个数
ZCARD key 
# 返回有序集key中成员member的排名
ZRANK key member 
# 返回存储在有序集合key中的指定范围的元素   order by id limit 1,100ZRANGE key start stop [WITHSCORES] 
# 返回有序集key中,指定区间内的成员(逆序)ZREVRANGE key start stop [WITHSCORES]

redis pipeline

客户端一般的机制是客户端发送请求给redis,等待响应回来后再发下一个命令。

pipeline是客户端提供的机制,通过一次发送多次请求命令,减少网络传输事件。如下图

redis事务

redis事务其实可以类比原子操作来理解

在多核的时候我们探讨原子操作,在多条并发连接的时候探讨事务。

事务是用户定义的一系列数据库操作,这些操作视为一个完整的逻辑处理工作单元,要么全都执行,要么全部不执行,是不可分割的工作单元。

指令

MULTI

开启事务

EXEC

提交事务

DISCARD

取消事务

WATCH

检测 key 的变动,若在事务执行中,key 变动则取消事务;在事务开启前调用,乐观锁实现。

具体应用

 WATCH zsetelement = ZRANGE zset 0 0MULTIZREM zset elementEXEC

注意这里使用的是乐观锁,即默认不会有别的连接来变动key,如果有key的变动,那么执行失败

lua脚本

lua 脚本实现原子性,redis 中加载了一个 lua 虚拟机,用来执行 redis lua 脚本,redis lua 脚本的执行是原子性的,当某 个脚本正在执行的时候,不会有其他命令或者脚本被执行,lua 脚本当中的命令会直接修改数据状态,lua 脚本 mysql 存储区别:MySQL存储过程不具备事务性,所以也不具备原子性。

# 从文件中读取 lua脚本内容
cat test1.lua | redis-cli script load --pipe# 加载 lua脚本字符串 生成 sha1> script load 'local val = KEYS[1]; return val'"b8059ba43af6ffe8bed3db65bac35d452f8115d8"# 检查脚本缓存中,是否有该 sha1 散列值的lua脚本
> script exists "b8059ba43af6ffe8bed3db65bac35d452f8115d8"1) (integer) 1# 清除所有脚本缓存
> script flushOK# 如果当前脚本运行时间过长(死循环),可以通过 script kill 杀死当前运行的脚本
> script kill(error) NOTBUSY No scripts in execution right now.

有了sha1散列值就可以通过值来运行已经编译的脚本。

EVAL

# 测试使用
EVAL script numkeys key [key ...] arg [arg ...]

EVALSHA

# 线上使用
EVALSHA sha1 numkeys key [key ...] arg [arg ...]

redis的ACID特性分析

A 原子性;事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败;redis 不支持回滚;即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直 到将事务队列中的所有命令都执行完毕为止。

C 一致性;事务的前后,所有的数据都保持一个一致的状态,不能违反数据的一致性检测;这里 的一致性是指预期的一致性而不是异常后的一致性;所以 redis 也不满足;这个争议很大:redis 能 确保事务执行前后的数据的完整约束;但是并不满足业务功能上的一致性;比如转账功能,一个扣 钱一个加钱;可能出现扣钱执行错误,加钱执行正确,那么最终还是会加钱成功;系统凭空多了 钱;

I 隔离性;各个事务之间互相影响的程度;redis 是单线程执行,天然具备隔离性;

D 持久性;redis 只有在 aof 持久化策略的时候,并且需要在 appendfsync=always 才具备持久性;实际项目中几乎不会使用 redis.conf 中 aof 持久化策略;

面试时候回答:lua 脚本满足原子性和隔离性;一致性和持久性不满足。

redis异步连接

首先我们要明确实现异步连接要用什么库,我们为了异步连接需要做什么。

hiredis库里已经完成了协议解析,读写事件,缓冲区操作,协议加密

我们需要适配事件对象  适配事件操作函数即可。

更多资料在:https://github.com/0voice查询

http://www.dtcms.com/a/321825.html

相关文章:

  • 【数字投影】艺术视觉在展厅中的多维传达与设计创新
  • 【MySQL】初识索引
  • 51c视觉~合集16
  • 批量把在线网络JSON文件(URL)转换成Excel工具 JSON to Excel by WTSolutions
  • NOIP 2024 游记
  • 不同的子序列-二维动态规划
  • GeeLark 7月功能更新回顾
  • 【补题】Codeforces Round 776 (Div. 3) E. Rescheduling the Exam
  • 三方相机问题分析七:【datespace导致GPU异常】三方黑块和花图问题
  • 显示器同步技术终极之战:G-Sync VS. FreeSync
  • xml 格式化
  • 卷板矫平机:把“翘脾气”的金属板材变平整
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘huggingface_hub’问题
  • C# 装箱拆箱
  • 数据结构进阶 详谈红黑树
  • Redis(⑤-线程池隔离)
  • javaSE(基础):5.抽象类和接口
  • C+++——内存管理
  • 大语言模型提示工程与应用:提示工程入门指南
  • 前端后端之争?JavaScript和Java的特性与应用场景解析
  • 大型语言模型幻觉检测与缓解技术研究综述
  • 将Django项目部署到Vercel平台的完整指南
  • Spring Boot 常用注解及其功能详解
  • Numpy科学计算与数据分析:Numpy高效数据处理与优化
  • 第七章:数据持久化 —— `chrome.storage` 的记忆魔法
  • bytearray和bytes
  • 解决flex元素内部文本溢出的问题min-width: 0
  • Pytest项目_day08(setup、teardown前置后置操作)
  • 树和二叉树和算法复杂度
  • 这款MEMS组合导航系统如何实现高性价比?