热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【起】Redis基础篇——基本数据结构之ZSet,Bitmap…

前言距离过年那会闲在家更新的MySQL系列已经过去一段时间了,这段时间一直在忙其他的,所以博客的更新也就搁置了,但是一直在想着要更新啥内
前言

距离过年那会闲在家更新的 MySQL 系列已经过去一段时间了,这段时间一直在忙其他的,所以博客的更新也就搁置了,但是一直在想着要更新啥内容比较好,刚好朋友给了我一本 Redis 的书籍,我就打算看完结合官方的文档总结一下,分享给大家,如果有什么不对的地方请指正。

Redis 系列,我想以“起承转合”的形式来更新,不过不一定是四篇噢,因为篇幅有限,太长怕你们没有耐心看完,可能《起》篇就分为几篇博文来叙述了,我也会对其进行规整,方便大家看完能更好的吸收,毕竟写文章的我能得到各位观看我的文章,是我的荣幸,我必须得对大家负责的嘛~

话归正题,Redis 应该很多人都有用过(没用过应该看这篇也能看得懂,但是一些基本理论就得自己上网百度啦)。至于 Redis 是什么,有什么好处,怎么用,那就继续往下看吧~本文会侧重于让大家对Redis 基本数据类型的操作命令,底层存储结构以及其应用场景得到一定的认知。

附上基础篇的脑图(上传平台有压缩,有兴趣可以到我的公众号【6曦轩】领取原图)
在这里插入图片描述

今天这一篇章给大家介绍一下 Redis 的基本数据类型(高阶的暂不介绍)。

篇幅有点长,我分了几篇来写,这篇是继前面两章节之后的,主要介绍 Zset 以及 Bitmap。

正文

Redis 基本数据类型(ZSet,Bitmap…)


ZSet 有序集合


存储类型

在这里插入图片描述
sorted set,有序的 set,每个元素有个 score。
score 相同时,按照 key 的 ASCII 码排序。
数据结构对比:

数据结构是否允许重复元素是否有序有序实现方式
列表 list索引下标
集合 set
有序集合 zset分值 score

操作命令

添加元素
zadd myzset 10 java 20 php 30 ruby 40 cpp 50 python

获取全部元素
zrange myzset 0 -1 withscores
zrevrange myzset 0 -1 withscores

根据分值区间获取元素
zrangebyscore myzset 20 30

移除元素
也可以根据 score rank 删除
zrem myzset php cpp

统计元素个数
zcard myzset

分值递增
zincrby myzset 5 python

根据分值统计个数
zcount myzset 20 60

获取元素 rank
zrank myzset java

获取元素 score
zsocre myzset java

也有倒序的 rev 操作(reverse)

存储(实现)原理

同时满足以下条件时使用 ziplist 编码:

  • 元素数量小于 128 个

  • 所有 member 的长度都小于 64 字节

在 ziplist 的内部,按照 score 排序递增来存储。插入的时候要移动之后的数据。

对应 redis.conf 参数:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

超过阈值之后,使用 skiplist+dict 存储。

  • 问题:什么是 skiplist?

我们先来看一下有序链表:
在这里插入图片描述
在这样一个链表中,如果我们要查找某个数据,那么需要从头开始逐个进行比较,直到找到包含数据的那个节点,或者找到第一个比给定数据大的节点为止(没找到)。也就是说,时间复杂度为 O(n)。同样,当我们要插入新数据的时候,也要经历同样的查找过程,从而确定插入位置。

而二分查找法只适用于有序数组,不适用于链表。

假如我们每相邻两个节点增加一个指针(或者理解为有三个元素进入了第二层),让指针指向下下个节点。
在这里插入图片描述

这样所有新增加的指针连成了一个新的链表,但它包含的节点个数只有原来的一半(上图中是 7, 19, 26)。在插入一个数据的时候,决定要放到那一层,取决于一个算法(在 redis 中 t_zset.c 有一个 zslRandomLevel 这个方法)。

现在当我们想查找数据的时候,可以先沿着这个新链表进行查找。当碰到比待查数据大的节点时,再回到原来的链表中的下一层进行查找。比如,我们想查找 23,查找的路径是沿着下图中标红的指针所指向的方向进行的:
在这里插入图片描述

  1. 23 首先和 7 比较,再和 19 比较,比它们都大,继续向后比较。

  2. 但 23 和 26 比较的时候,比 26 要小,因此回到下面的链表(原链表),与 22 比较。

  3. 23 比 22 要大,沿下面的指针继续向后和 26 比较。23 比 26 小,说明待查数据23 在原链表中不存在

在这个查找过程中,由于新增加的指针,我们不再需要与链表中每个节点逐个进行比较了。需要比较的节点数大概只有原来的一半。这就是跳跃表。

  • 为什么不用 AVL 树或者红黑树?

因为 skiplist 更加简洁。

源码:server.h

typedef struct zskiplistNode {sds ele; /* zset 的元素 */double score; /* 分值 */struct zskiplistNode *backward; /* 后退指针 */struct zskiplistLevel {struct zskiplistNode *forward; /* 前进指针,对应 level 的下一个节点 */ unsigned long span; /* 从当前节点到下一个节点的跨度(跨越的节点数) */} level[]; /* 层 */
} zskiplistNode;typedef struct zskiplist {struct zskiplistNode *header, *tail; /* 指向跳跃表的头结点和尾节点 */ unsigned long length; /* 跳跃表的节点数 */ int level; /* 最大的层数 */
} zskiplist;typedef struct zset {dict *dict;zskiplist *zsl;
} zset;

随机获取层数的函数:

源码:t_zset.c

int zslRandomLevel(void) {int level &#61; 1;while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))level &#43;&#61; 1;return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

应用场景

  • 排行榜
    id 为 6001 的新闻点击数加 1&#xff1a;zincrby hotNews:20190926 1 n6001
    获取今天点击最多的 15 条&#xff1a;zrevrange hotNews:20190926 0 15 withscores

其他数据结构简介

https://redis.io/topics/data-types-intro

在这里插入图片描述

BitMaps

Bitmaps 是在字符串类型上面定义的位操作。一个字节由 8 个二进制位组成。
在这里插入图片描述

set k1 a

获取 value 在 offset 处的值&#xff08;a 对应的 ASCII 码是 97&#xff0c;转换为二进制数据是 01100001&#xff09;
getbit k1 0

修改二进制数据&#xff08;b 对应的 ASCII 码是 98&#xff0c;转换为二进制数据是 01100010&#xff09;

setbit k1 6 1
setbit k1 7 0
get k1

统计二进制位中 1 的个数
bitcount k1

获取第一个 1 或者 0 的位置

bitpos k1 1
bitpos k1 0

BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数&#xff1a;

BITOP AND destkey srckey1 … srckeyN &#xff0c;对一个或多个 key 求逻辑与&#xff0c;并将结果保存到 destkey

BITOP OR destkey srckey1 … srckeyN&#xff0c;对一个或多个 key 求逻辑或&#xff0c;并将结果保存到 destkey

BITOP XOR destkey srckey1 … srckeyN&#xff0c;对一个或多个 key 求逻辑异或&#xff0c;并将结果保存到 destkey

BITOP NOT destkey srckey&#xff0c;对给定 key 求逻辑非&#xff0c;并将结果保存到 destkey


应用场景&#xff1a;

  • 用户访问统计
  • 在线用户统计
  • Hyperloglogs

Hyperloglogs&#xff1a;提供了一种不太准确的基数统计方法&#xff0c;比如统计网站的 UV&#xff0c;存在一定的误差。- --------
HyperLogLogTest.java


  • Streams

5.0 推出的数据类型。支持多播的可持久化的消息队列&#xff0c;用于实现发布订阅功能&#xff0c;借鉴了 kafka 的设计。


By the way

有问题&#xff1f;可以给我留言或私聊
有收获&#xff1f;那就顺手点个赞呗~

当然&#xff0c;也可以到我的公众号下「6曦轩」&#xff0c;

回复“学习”&#xff0c;即可领取一份
【Java工程师进阶架构师的视频教程】~


回复“面试”&#xff0c;可以获得&#xff1a;
【本人呕心沥血整理的 Java 面试题】


回复“MySQL脑图”&#xff0c;可以获得
【MySQL 知识点梳理高清脑图】


还有【阿里云】【腾讯云】的购买优惠噢~具体请联系我

曦轩我是科班出身的程序员&#xff0c;php&#xff0c;Android以及硬件方面都做过&#xff0c;不过最后还是选择专注于做 Java&#xff0c;所以有啥问题可以到公众号提问讨论&#xff08;技术情感倾诉都可以哈哈哈&#xff09;&#xff0c;看到的话会尽快回复&#xff0c;希望可以跟大家共同学习进步&#xff0c;关于服务端架构&#xff0c;Java 核心知识解析&#xff0c;职业生涯&#xff0c;面试总结等文章会不定期坚持推送输出&#xff0c;欢迎大家关注~~~
在这里插入图片描述


推荐阅读
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了关于apache、phpmyadmin、mysql、php、emacs、path等知识点,以及如何搭建php环境。文章提供了详细的安装步骤和所需软件列表,希望能帮助读者解决与LAMP相关的技术问题。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 2022年的风口:你看不起的行业,真的很挣钱!
    本文介绍了2022年的风口,探讨了一份稳定的副业收入对于普通人增加收入的重要性,以及如何抓住风口来实现赚钱的目标。文章指出,拼命工作并不一定能让人有钱,而是需要顺应时代的方向。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
author-avatar
xxyyxx1952
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有