IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Redis五种数据结构原理及应用场景 -> 正文阅读

[大数据]Redis五种数据结构原理及应用场景

前言

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件; 下面就了解的应用场景及其原理做个总结:

String类型

介绍

存储字符串类型的key-value

常用命令及应用场景

常见命令命令介绍应用场景
set/get/setex存储字符串类型的key-value验证码、幂等性(重复提交判断)、token令牌、 序列化json对象存储set user:captcha:zhangsan 123456 ex 30/setex user:captcha:zhangsan 30 123456 (张三收到验证码为123456,30s后失效),set user:zhangsan 用户信息json串(用户张三的个人信息)
mset/mget批量设置key-value同set/getmset user:name zhangsan user:age 20 (用户姓名为张三,年龄20)
incr对key对应的值进行加1操作,并返回新值统计、计数器、发号器incr article:123:reading(对id为123的文章阅读量增加1)
incrby对key对应的值进行加increment操作,并返回新值同incrincr article:123:reading 10(对id为123的文章阅读量增加10)
setnxkey如果存在则返回0,不存在则返回1分布式锁setnx addr 123(设置地址为123)
getset设置key的值,并返回key的旧值状态变更(比如用户下单,可以修改下单状态)getset addr 567(注意:返回为旧值123)

原理

Redis的字符串是动态字符串,是可以修改的字符串,它的内部表示就是一个字符数组,内部结构的实现类似于Java的ArrayList,它的内部结构是一个带长度信息的字节数组

注意

  • 值的长度不能超过512MB
  • key的命名规范,不要过长,冒号分割, 业务名:表名:ID

List

介绍

  • 字符串列表,按照插入顺序排序

常用命令及应用场景

常见命令命令介绍应用场景
lpush/rpush将一个或多个值插入到列表头部(左边)/(右边)最新评论列表/非实时榜单(定时计算榜单,如手机日销榜单)lpush phone:rank:daily iphone13 xiaomi12 huaweiP50 (手机日销榜 第一华为,第二小米12,第三苹果)
lpop/rpop移除并获取列表最左边/右边一个元素-rpop phone:rank:daily (移除key phone:rank:daily最右边一个元素)
llen获取列表长度-llen phone:rank:daily(获取key phone:rank:daily的列表长度)
lindex通过索引获取列表中元素-lindex phone:rank:daily 0 (获取第一个元素)
lrange获取key对应的list指定下标范围的元素(-1表示所有元素)-lrange phone:rank:daily 0 -1 (获取列表所有元素)
brpop移除并获取列表最右边一个元素(如果没有元素则阻塞)简单队列brpop phone:rank:daily 30(监听key phone:rank:daily最右边一个元素,监听时间30S)
lrem移除元素指定个数-lrem phone:rank:daily 1 iphone13(phone:rank:daily队列移除一个iphone13元素)

原理

  • 双向链表,插入删除时间复杂度O(1)快,查找为O(n)慢

注意

  • 通常添加一个元素到列表的头部(左边)或者尾部(右边)。
  • 存储的都是String字符串类型。
  • 支持分页操作,高并发项目中,第一页数据都是来源list,第二页和更多信息则是通过数据库加载。
  • 一个列表最多可以包含232-1个元素(最好不要超过1K)。

Hash

介绍

  • 一个String类型的filed和value的映射表,hash特别适合用于存储对象。

常用命令及应用场景

常见命令命令介绍应用场景
hset/hget/hgetall设置/得到 key指定的哈希集中指定字段值用户个人信息、商品详情hset product:detail:1 title iphone13(设置id为1的商品详情 其中标题为iPhone13)
hmset/hmget批量设置/得到 key指定的哈希集中指定字段值用户个人信息、商品详情hset product:detail:1 title iphone13 price 6999 stock 10(设置id为1的商品详情 其中标题为iPhone13,价格为6999,库存为10件)
hincrby增加key指定的hash集中指定字段数值购物车增加或减少hincrby product:detail:1 stock 1(id为1的商品增加一件库存)
hdel从key指定的hash集中移除指定域-hdel product:detail:1 stock(移除id为1的商品的库存信息)
hexists返回hash里边field是否存在(存在是1,不存在未0)-hexists product:detail:1 stock (id为1的商品库存信息是否存在)

原理

  • 哈希对象的编码有两种,分别是:ziplist(见下文补充)、hashtable。

  • 当哈希对象保存的键值对数量小于 512,并且所有键值对的长度都小于 64 字节时,使用ziplist(压缩列表)存储;否则使用 hashtable 存储。

如何解决hash冲突

  • Redis 采用了渐进式 rehash 策略.这也是 hash 中最重要的部分。
  • redis在扩容的时候执行 rehash 策略会保留新旧两个 hashtable 结构,查询时也会同时查询两个 hashtable.Redis会将旧 hashtable 中的内容一点一点的迁移到新的 hashtable 中,当迁移完成时,就会用新的 hashtable 取代之前的.当 hashtable 移除了最后一个元素之后,这个数据结构将会被删除。
  • 正常情况下,当 hashtable 中元素的个数等于数组的长度时,就会开始扩容,扩容的新数组是原数组大小的 2 倍.如果 Redis 正在做 bgsave(持久化) 时,可能不会去扩容,因为要减少内存页的过多分离(Copy On Write).但是如果 hashtable 已经非常满了,元素的个数达到了数组长度的 5 倍时,Redis 会强制扩容。
  • 当hashtable 中元素逐渐变少时,Redis 会进行缩容来减少空间占用,并且缩容不会受 bgsave 的影响,缩容条件是元素个数少于数组长度的 10%。

注意

  • 每个hash可以存储232 -1键值对(40多亿)

Set

介绍

将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略

常用命令及应用场景

常见命令命令介绍应用场景
sadd添加一个或多个元素到集合key中,如果已经在集合key中则忽略去重、社交应用关注、粉丝、用户标签sadd user:1:tags:hangzhou(id为1的用户来自杭州)
scard返回集合存储key的基数粉丝数量、统计网站PV、UV、IP数scard user:1:fans 用户id为1的粉丝数量为多少
sdiff返回两个集合的差集商品推荐sdiff user:1:tags user:2:tags(用户id为1的与用户id为2的标签差集)
sinter返回指定所有集合的成员交集共同好友、共同关注sinter user:1:tags user:2:tags(用户id为1的与用户id为2的标签交集)
sismember判断是否是集合中成员-sismember user:1:tags:hangzhou (user:1:tags中是否存在hangzhou标签)
srem移除key集合指定元素-srem user:1:tags:hangzhou(移除user:1:tags中标签hangzhou)
sunion返回多个集合的并集-sunion user:1:tags user:2:tags(用户id为1的与用户id为2的标签并集)

原理

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

注意

  • 集合是通过哈希表来实现的

SortedSet

介绍

  • 用于将一个或多个元素及其分数值加入到有序集当中。
  • 如果某个成员已存在,那么更新这个分值。

常用命令及应用场景

常见命令命令介绍应用场景
zadd向有序集合添加一个或多个成员实时排行榜(商品热销榜、积分榜)zadd shop:rank 90 iphone 80 huawei(商品排行榜iPhone第一,华为第二)
zcard获取有序集合的成员数榜单数量zcard shop:rank(获取集合shop:rank数量)
zcount计算有序集合中指定区间分数的成员数统计数量zcount shop:rank 80 90(返回销量为80-90的品牌数)
zincrby有序集合中对指定成员的分数加上增量实时增加销量zincrby shop:rank 10 huawei(华为手机销量增加10)
zrange/zrevrange通过索引区间返回有序集合指定区间内的成员,分数值递增(从小到大)/(从大到小)榜单排名zrange shop:rank 0 -1(返回商品榜单)
zrevrank/zrank返回集合中成员排第几(从大到小)/(从小到大)榜单具体排名情况zrevrank shop:rank iphone
zrem删除集合中一个或多个元素-zrem shop:rank iphone huawei(移除商品排行榜中苹果和华为)
zscore返回集合中成员分数值查看具体某个商品积分zscore shop:rank iphone(查看iPhone手机销量)

原理

  • 底层使用Ziplist压缩列表和"跳跃表"两种存储结构

注意

如果重复添加相同的数据,score的值将被反复覆盖,保留最后一次修改的结果。


补充

跳跃表简单介绍

举例:
比如找78
正常 1-> 4->7->13->16->25->57->78 8次
跳跃表如图 1->7->16->57->79(发现比78小,又没找到;往下一层走)->78 6次
如果数据量大速度提升则更明显
在这里插入图片描述

压缩表简单介绍

举例:
我们知道,数组要求每个元素的大小相同,如果我们要存储不同长度的字符串,那我们就需要用最大长度的字符串大小作为元素的大小(假设是20个字节)。存储小于 20 个字节长度的字符串的时候,便会浪费部分存储空间。
在这里插入图片描述

数组的优势占用一片连续的空间可以很好的利用CPU缓存访问数据。如果我们想要保留这种优势,又想节省存储空间我们可以对数组进行压缩。

在这里插入图片描述

但是这样有一个问题,我们在遍历它的时候由于不知道每个元素的大小是多少,因此也就无法计算出下一个节点的具体位置。这个时候我们可以给每个节点增加一个lenght的属性。

在这里插入图片描述
如此。我们在遍历节点的之后就知道每个节点的长度(占用内存的大小),就可以很容易计算出下一个节点再内存中的位置。这种结构就像一个简单的压缩列表了。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 11:59:11  更:2022-01-28 12:00:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 14:00:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码