SQL实践篇(三):什么是Redis

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: SQL实践篇(三):什么是Redis

 

简介

Redis是一种基于内存的键值数据库,键值数据库会使用哈希表存储key和value。其中key和value可以是任何内容,无论是简单对象还是复杂对象。

键值数据库是NoSQL思想,其规则是"只提供你想要的",因此模型很灵活,查询效率也高,成本也低。

而RDBMS是建立在关系模型的基础上,强调的是数据的一致性和各种约束条件,成本很高。

本节我们将从以下几个方面,简单了解下Redis:

· Redis是什么,为什么它这么快?

· Redis支持的数据类型都有哪些?

Redis是什么,为什么这么快?

Redis,全称是REmote Dictionary Server

Redis的查询效率非常高,根据官方的数据,Redis每秒最多处理的请求可以达到10w次。

为什么这么快呢?

Redis是采用ANSI C语言编写的,跟SQLite一样。这样的好处是底层代码执行效率更高,相比面向对象的语言,依赖性也更低。系统兼容性好,稳定性高。

 

另外,Redis是基于内存的数据库,没有磁盘IO的限制,自然快的飞起。

 

其次,数据结构简单,采用key-value的方式进行存储,也就是使用Hash结构进行操作,数据的操作复杂度为O(1)。

 

但是Redis快的原因远不止这些,还有很多各种各样的原因,比如说它采用单进程单线程的模型,避免了上下文切换和不必要的线程资源争抢问题。

 

在技术上,Redis还采用了多路IO复用技术。这里的多路指的是多个socket网络连接,复用指的是复用同一个线程。这样的好处是可以在同一个线程中处理多个IO请求,尽量减少网络IO的损耗。

 

可以看到,Redis可以说是把效率做到了极致,各方各面可能存在的时间消耗都被优化过。

 

2023-11-10 00:47:47 不过,在2020年新推出的Redis6.0版本里,还是引进了多线程模型,来提高Redis的性能和并发能力。不过Redis默认情况下不会开启多线程模式,官方建议是除非达到了性能瓶颈,否则没必要开启多线程。

Redis的数据类型

Memcached也是一个键值型数据库,但与它相比,Redis还有一个非常大的优势,就是支持多种数据类型。

 

Redis支持的数据类型包括字符串、哈希、列表、集合、有序集合等。

 

字符串

字符串类型是Redis提供的最基本的数据类型。对应的结构是key-value

 

如果我们想要设置某个键的值,可以使用set key value,如果想要获取某个值,那就用get key。如图:

image.png

Hash

哈希(hash)进一步提供了字段和字段值的映射,对应的结构是key-field-value。

设置某个键的哈希值hset key field value

比如说要给user1设置username为zhangfei,设置age为28,可以写成:

image.png


或者可以连写成:

image.png

取出某个键的某个field字段hget key field

比如说hget user1 username

一次性取出某个键的多个field字段hmget key field_1 field_2...

比如说hmget user1 usename age

image.png

字符串列表

字符串列表(list)的底层是一个双向链表结构,所以我们可以向链表的两头添加元素,时间复杂度都是O(1),同时我们也可以比较方便的获取列表中的某个片段。

向列表左侧添加元素LPUSH key value [...]

比如说我要在heroslist列表左侧添加zhagnfei、guanyu、liubei这三条数据,可以写成:

image.png

向列表右侧添加元素RPUSH key value [...]

获取某一片段的内容

image.png

如获取herolist从0到4位置的数据,写成:LRANGE herolist 0 4即可。

image.png


字符串集合

字符串集合(set)是字符串类型的无序集合,与列表(list)的区别是集合内的元素是无序且不重复的。

在集合中添加元素SADD key member [....]

比如我想在heroSet集合添加zhangfei、guanyu、liubei、dianwei和lvbu这五个元素,可以写成:

image.png

在集合中删除元素SREM key member [....]

比如我们想在heroSet集合中删除liubei和lvbu两个元素,可以写成:

image.png

获取集合内全部元素SISMEMBER key

比如我想获取heroSet集合中的所有元素,可以写成(可以理解成s is member):

image.png

判断集合内是否存在某个元素SISMEMBER key member

比如要判断集合中是否存在zhangfei和liubei,可以写成:

image.png

image.png

有序字符串集合

有序字符串集合(SortedSet,简称ZSET),可以理解成是集合的升级版,是内部有序的集合。

 

实际上,ZSET是在集合的基础上增加了一个分数属性,这个属性在添加和修改元素的时候可以被指定。每次指定后,ZSET都会按照分数来自动排序。

 

有序集合跟列表有一定程度上的相似性。比如这俩都是有序的,都可以获取某一范围内的数据,但是它们在数据结构上有很大的不同。

 

列表是通过双向链表的结构来实现的,因此在操作左右两侧的数据时比较快,但是越到中间的数据,操作的越慢,整体查询的时间复杂度是O(n)。

 

有序集合的实现结构比较复杂,它在内部是通过Hash表的形式来存储所有元素和分数,因此查找指定元素的分数时,时间复杂度是O(1),因为通过哈希值可以直接找到位置。

同时它还通过跳表(skiplist)来维护元素的顺序,类似二叉树或者二分查找,不管读哪部分的数据都会比较快,因此涉及到顺序的操作时,查询的时间复杂度是O(log(N))。同时有序集合可以通过score来灵活调整元素位置,但是列表就不行了,它调整比较麻烦。

 

什么是跳表呢?在参考文献4里扒了一张图,描述的很形象:

image.png

其实非常类似B+树结构。

 

假设链表有N个节点,每2个节点生成一个上层索引,则第一层索引的节点数为N/2,第二层则是第一层的一半,即N/4,依次类推,第h层的节点个数就是N / ( 2 h ) N/(2^h)N/(2

h

),因此整个跳表的高度就是l o g 2 ( N ) log_2(N)log

2

(N),跟二叉树一样了,所以查询的时间复杂度就是l o g ( N ) log(N)log(N)。

 

有兴趣了解跳表结构的话,可以看一下参考文献4,写的非常形象。

在有序列表中添加元素和分数ZADD key score member [...]

比如我们给heroScore集合添加下面5个英雄的hp_max数值作为score,如下表:

image.png

所以可以写成:

image.png

获取某个元素的分数ZSCORE key member

比如获取关羽的分数:

image.png

删除一个或多个元素ZREM key member [member...]

比如删除guanyu这个元素:

image.png

获取某个范围内的元素列表

· ZRANGE key start stop [WITHSCORES]:按分数从小到大排序,即ASC;

· ZREVRANGE key start stop [WITHSCORES]:按分数从大到小排序,即DESC;

其中WITHSCORES是个可选项,加上的表示需要将分数一起显示出来。

比如说要查询heroScore这个有序集合中分数排名前3的英雄及数值,可以写成:

image.png

image.png

其他数据类型

除了以上5种数据类型之外,Redis还支持位图(Bitmaps)数据结构。

 

在2.8版本之后,增加了基数统计(HyperLogLog)。

 

3.2版本之后,加入了地理空间(Geospatial)以及索引半径查询的功能。

 

5.0版本,引入了数据流(Streams)数据类型。

总结

了解Redis还是非常重要的。在实际的工作中,我们经常会将RDBMS和Redis配合使用,优势互补。

 

作为常见的 NoSQL 数据库,Redis 比Memcached 的优势要高很多:

 

Redis支持的数据类型比 Memcached 丰富得多,

在 I/O 性能上,Redis 采用的是单线程 I/O 复用模型,而 Memcached 是多线程,可以利用多核优势。

在持久化上,Redis 提供了两种持久化的模式(RDB和AOF),可以让数据永久保存,这是 Memcached 不具备的。

MongoDB里可以通过mmp调用来将数据映射到内存中。可以将mmp理解成是一种加速的手段。其将文件映射到调用进程的地址空间里,实现了文件所在的磁盘物理地址与进程空间的虚拟地址一一映射的关系,这样就可以直接在内存中进行操作,然后写完成之后同步一下就可以存放到文件中,效率非常高。有兴趣可以去了解一下。

 

另外,Redis中的有序集合比较特殊,它通过Hash表的形式来存储所有元素和分数,同时使用跳表来维护元素的顺序。因此不同场景下的查询时间复杂度会有不同。

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
目录
相关文章
|
11月前
|
存储 缓存 NoSQL
深入理解Django与Redis的集成实践
深入理解Django与Redis的集成实践
301 0
|
2月前
|
SQL Java 关系型数据库
在 RDB 上跑 SQL------SPL 轻量级多源混算实践 1
SPL 支持通过 JDBC 连接 RDB,可动态生成 SQL 并传参,适用于 Java 与 SQL 结合的各类场景。本文以 MySQL 为例,演示如何配置数据库连接、编写 SPL 脚本查询 2024 年订单数据,并支持参数过滤和 SQL 混合计算。脚本可在 IDE 直接执行或集成至 Java 应用调用。
|
13天前
|
SQL 关系型数据库 Java
SQL 移植--SPL 轻量级多源混算实践 7
不同数据库的 SQL 语法存在差异,尤其是函数写法不同,导致 SQL 移植困难。SPL 提供 sqltranslate 函数,可将标准 SQL 转换为特定数据库语法,实现 SQL 语句在不同数据库间的无缝迁移,支持多种数据库函数映射与自定义扩展。
|
5月前
|
SQL 存储 关系型数据库
SQL优化策略与实践:组合索引与最左前缀原则详解
本文介绍了SQL优化的多种方式,包括优化查询语句(避免使用SELECT *、减少数据处理量)、使用索引(创建合适索引类型)、查询缓存、优化表结构、使用存储过程和触发器、批量处理以及分析和监控数据库性能。同时,文章详细讲解了组合索引的概念及其最左前缀原则,即MySQL从索引的最左列开始匹配条件,若跳过最左列,则索引失效。通过示例代码,展示了如何在实际场景中应用这些优化策略,以提高数据库查询效率和系统响应速度。
171 10
|
5月前
|
SQL 安全 关系型数据库
SQL注入之万能密码:原理、实践与防御全解析
本文深入解析了“万能密码”攻击的运行机制及其危险性,通过实例展示了SQL注入的基本原理与变种形式。文章还提供了企业级防御方案,包括参数化查询、输入验证、权限控制及WAF规则配置等深度防御策略。同时,探讨了二阶注入和布尔盲注等新型攻击方式,并给出开发者自查清单。最后强调安全防护需持续改进,无绝对安全,建议使用成熟ORM框架并定期审计。技术内容仅供学习参考,严禁非法用途。
717 0
|
2月前
|
存储 缓存 NoSQL
Redis 核心知识与项目实践解析
本文围绕 Redis 展开,涵盖其在项目中的应用(热点数据缓存、存储业务数据、实现分布式锁)、基础数据类型(string 等 5 种)、持久化策略(RDB、AOF 及混合持久化)、过期策略(惰性 + 定期删除)、淘汰策略(8 种分类)。 还介绍了集群方案(主从复制、哨兵、Cluster 分片)及主从同步机制,分片集群数据存储的哈希槽算法。对比了 Redis 与 Memcached 的区别,说明了内存用完的情况及与 MySQL 数据一致性的保证方案。 此外,详解了缓存穿透、击穿、雪崩的概念及解决办法,如何保证 Redis 中是热点数据,Redis 分布式锁的实现及问题解决,以及项目中分布式锁
|
6月前
|
缓存 NoSQL Java
Redis应用—6.热key探测设计与实践
热key问题在高并发系统中可能导致数据层和服务层的严重瓶颈,如Redis集群瘫痪和用户体验下降。为解决此问题,京东开发了JdHotkey热key探测框架,具备实时性、准确性、集群一致性和高性能等特点。该框架由etcd集群、Client端jar包、Worker端集群和Dashboard控制台组成,通过分布式计算快速识别热key并推送至应用内存,有效减轻数据层负载,提升服务性能。JdHotkey适用于多种场景,安装部署简便,支持毫秒级热key探测和集群一致性维护。
287 61
Redis应用—6.热key探测设计与实践
|
4月前
|
缓存 NoSQL Java
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
93 5
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
|
12月前
|
SQL 存储 API
Flink实践:通过Flink SQL进行SFTP文件的读写操作
虽然 Apache Flink 与 SFTP 之间的直接交互存在一定的限制,但通过一些创造性的方法和技术,我们仍然可以有效地实现对 SFTP 文件的读写操作。这既展现了 Flink 在处理复杂数据场景中的强大能力,也体现了软件工程中常见的问题解决思路——即通过现有工具和一定的间接方法来克服技术障碍。通过这种方式,Flink SQL 成为了处理各种数据源,包括 SFTP 文件,在内的强大工具。
346 15
|
7月前
|
存储 缓存 NoSQL
Redis哈希结构在提升数据检索速度中的实践应用
本文详细介绍了 Redis 哈希结构的特点、常见使用场景以及如何在实际应用中利用哈希结构提升数据检索速度。通过合理使用 Redis 哈希结构,可以显著提高系统的性能和响应速度。在实际开发中,结合具体业务需求,灵活运用 Redis 提供的多种数据结构,构建高效的缓存和数据存储解决方案。希望本文能帮助您更好地理解和应用 Redis 哈希结构,提升数据检索速度。
172 18