【Redis破障之路】二:Redis安装和基本数据结构

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 【Redis破障之路】二:Redis安装和基本数据结构

 

1、安装Redis

Redis6.0在2020年已经发布,所以我们安装Redis3.0。😂

1.1、在Linux上安装Redis

我们在CentOS上安装Redis。常见的的有三种安装方式:

  • yum/apt软件管理软件安装
  • 源码的方式进行安装
  • 容器化安装

我们这里选择第二种方式:

  • 1)下载Redis指定版本的源码压缩包到当前目录
wget http://download.redis.io/releases/redis-3.0.7.tar.gz
  • 2)解压缩Redis源码压缩包
tar xzf redis-3.0.7.tar.gz
  • 3)建立一个redis目录的软连接,指向redis-3.0.7
ln -s redis-3.0.7 redis
  • 4)进入redis目录
 cd redis
  • 5)编译(编译之前确保操作系统已经安装gcc)
 make
  • 6)安装
make install

最后可以执行redis-cli–v查看Redis的版本

image.png

1.2、启动Redis

有三种方法启动Redis:默认配置、运行配置、配置文件启动。

我们这里用默认配置的方式启动Redis:

redis-server

image.png

一般在生产环境会使用配置文件启动的方式。

1.3、Redis命令行客户端

Redis服务已经启动,现在使用redis-cli来连接。

redis-cli -h 127.0.0.1 -p 6379

image.png

2、Redis基本数据结构

Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。

image.png

2.1、字符串

字符串类型是Redis最基础的数据结构。所有的键都是字符串类型,

Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结构的差异就在于 value 的结构不一样。

image.png

而且其他几种数据结构都是在字符串类型基础上构建的,所以字符串类型能为其他四种数据结构的学习奠定基础。

除了上图描述简单的字符串,字符串类型的值也可以是复杂的字符串(例如JSON、XML)、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能 超过512MB。

image.png

2.1.1、命令

  • 设置值
set key value [ex seconds] [px milliseconds] [nx|xx]

下面操作设置键为Hello,值为World的键值对,返回结果为OK代表设置成功:

127.0.0.1:6379> set Hello World 
OK

set命令有几个选项:

  • ex seconds:为键设置秒级过期时间。
  • px milliseconds:为键设置毫秒级过期时间。
  • nx:键必须不存在,才可以设置成功,用于添加。
  • xx:与nx相反,键必须存在,才可以设置成功,用于更新。
  • 获取值
get key

下面操作获取键Hello的值:

127.0.0.1:6379> get Hello
"World"

如果要获取的键不存在,则返回nil(空):

127.0.0.1:6379> get some
(nil)
  • 批量设置值
mset key value [key value ...]

可以批量对多个字符串进行读写,节省网络耗时开销。

下面操作通过mset命令一次性设置4个键值对:

127.0.0.1:6379> mset a 1 b 2 c 3 d 4 
OK
  • 批量获取值
mget key [key ...] 

下面操作批量获取了键a、b、c、d的值:

127.0.0.1:6379> mget a b c d
1) "1"
2) "2"
3) "3"
4) "4"
  • 计数
incr key 

incr命令用于对值做自增操作,返回结果分为三种情况:

  • 值不是整数,返回错误。
  • 值是整数,返回自增后的结果。
  • 键不存在,按照值为0自增,返回结果为1。
127.0.0.1:6379>  set age 18
OK
127.0.0.1:6379> incr age
(integer) 19

除了incr命令,Redis提供了decr(自减)、incrby(自增指定数字)、 decrby(自减指定数字)、incrbyfloat(自增浮点数)。

2.1.2、应用场景

字符串可以说是Redis应用最广泛的数据结构,我们来看一下在实际的开发中一些典型的应用场景。

2.1.2.1、缓存功能

下图示比较典型的缓存使用场景,其中Redis作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。

image.png

2.1.2.2、计数

许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、 查询缓存的功能,同时数据可以异步落地到其他数据源。例如记录文章的阅读次数。

2.1.2.3、共享Session

用于分布式应用的Session共享,保证用户登录一次即可访问所有服务。

image.png

2.1.2.4、分布式锁

利用setnx命令可以实现分布式锁,由于Redis的单线程命令处理机制,如果有多个客户端同时执行setnx key value, 根据setnx的特性只有一个客户端能设置成功,所以setnx可以作为分布式锁的一种实现方案。

以下是最简单的Redis分布式锁实现示意图:

image.png

2.2、哈希

Redis 的字典和 Java 语言里面的 HashMap类似。在Redis中,哈希类型是指键值本身又是一个键值对结构,形如value={{field1,value1},…{fieldN,valueN}}

image.png

2.2.1、命令

  • 设置值
hset key field value

下面为user:1添加一对field-value:

127.0.0.1:6379> hset user:1 name tom 
(integer) 1

如果设置成功会返回1,反之会返回0。此外Redis提供了hsetnx命令,它们的关系就像set和setnx命令一样,只不过作用域由键变为field。

  • 获取值
hget key field 

获取user:1的name域(属性)对应的值:

127.0.0.1:6379> hget user:1 name 
"tom"
  • 删除field
hdel key field [field ...]

hdel会删除一个或多个field,返回结果为成功删除field的个数,例如:

127.0.0.1:6379> hdel user:1 name 
(integer) 1 
127.0.0.1:6379> hdel user:1 age 
(integer) 0
  • 批量设置或获取field-value
hmget key field [field ...] 
hmset key field value [field value ...]

hmset和hmget分别是批量设置和获取field-value,hmset需要的参数是key和多对field-value,hmget需要的参数是key和多个field。例如:

127.0.0.1:6379> hmset user:1 name mike age 12 city tianjin 
OK
127.0.0.1:6379> hmget user:1 name city 
1) "mike" 
2) "tianjin"

2.2.2、应用场景

2.2.2.1、存储对象

hash的filed-value的结构非常适合用来存储对象,field用来存储属性名称,value用来存储属性值。在一些客户端里也提供了json序列化器。

image.png

2.3、列表

Redis 的列表类似于 Java 语言里面的 LinkedList,同样地list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为O(n)。

那么,同样地,list也可以充当栈和队列的角色。

例如,在list两端的插入和弹出,可以模拟栈的操作:

image.png

列表类型有两个特点:第一、列表中的元素是有序的,这就意味着可以通过索引下标获取某个元素或者某个范围内的元素列表。第二、列表中的元素可以是重复的。

2.3.1、命令

列表主要有5种操作类型:

操作类型 操作
添加 rpush lpush linsert
查找 lrange lindex llen
删除 lpop rpop lren ltrim
修改 lset
阻塞操作 blpop brpop
  • 添加操作

从右边插入元素

rpush key value [value ...]

下面代码从右向左插入元素c、b、a:

127.0.0. 1:6379> rpush listkey c b a 
(integer) 3

lrange0-1命令可以从左到右获取列表的所有元素:

127.0.0.1:6379> lrange listkey 0 -1 
1) "c" 
2) "b" 
3) "a"

从左边插入元素类似,不再赘述

  • 向某个元素前或者后插入元素
linsert key before|after pivot value

linsert命令会从列表中找到等于pivot的元素,在其前(before)或者后 (after)插入一个新的元素value,例如下面操作会在列表的元素b前插入 java:

127.0.0.1:6379> linsert listkey before b java 
(integer) 4

返回结果为4,代表当前命令的长度,当前列表变为:

127.0.0.1:6379> lrange listkey 0 -1 
1) "c" 
2) "java" 
3) "b" 
4) "a"
  • 查找

获取指定范围内的元素列表

lrange key start end

lrange操作会获取列表指定索引范围所有的元素。

例如想获取列表的第2到第4个元素:

127.0.0.1:6379> lrange listkey 1 3 
1) "java" 
2) "b" 
3) "a"

获取列表指定索引下标的元素

lindex key index

例如当前列表最后一个元素为a:

127.0.0.1:6379> lindex listkey -1 
"a"

获取列表长度

llen key

例如,下面示例当前列表长度为4:

127.0.0.1:6379> llen listkey 
(integer) 4
  • 删除

从列表左侧弹出元素

lpop key

从列表右侧弹出

rpop key

删除指定元素

lrem key count value
  • 修改
lset key index newValue
  • 阻塞操作

阻塞式弹出如下:

blpop key [key ...] timeout 
brpop key [key ...] timeout

blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同。

2.3.2、应用场景

2.3.2.1、消息队列

Redis的lpush+brpop命令组合即可实现阻塞队列,生产客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

image.png

list可以灵活组合,在不同的场景使用,总结如下:

  • lpush+lpop=Stack(栈)
  • lpush+rpop=Queue(队列)
  • lpsh+ltrim=Capped Collection(有限集合)
  • lpush+brpop=Message Queue(消息队列)

2.4、集合

集合类似Java语言中的HashSet,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。

2.4.1、命令

2.4.1.1、集合内操作

  • 添加元素
sadd key element [element ...]

无法添加重复元素,添加重复元素会返回0。

  • 删除元素
srem key element [element ...]
  • 计算元素个数
scard key
  • 从集合随机弹出元素
spop key

2.4.1.2、集合间操作

  • 求多个集合的交集
sinter key [key ...]
  • 求多个集合的并集
suinon key [key ...]
  • 求多个集合的差集
sdiff key [key ...]

image.png

2.4.2、应用场景

2.4.2.1、标签

集合类型比较典型的使用场景是标签(tag)。例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣点就是标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共  同喜好的标签,这些数据对于用户体验以及增强用户黏度比较重要。

2.4.2.2、共同关注

可以利用交集的运算,实现社交社区用户的“共同关注”功能。

2.5、有序集合

zset 可能是 Redis 提供的最为特色的数据结构,它类似于 Java 的 SortedSet 和 HashMap  的结合体,一方面它是一个 set,保证了内部value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value  的排序权重。

image.png

有序集合提供了获取指定score和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助

我们在实际开发中解决很多问题。

有序集合中的元素不能重复,但是score可以重复,就和一个班里的同学学号不能重复,但是考试成绩可以相同。

2.5.1、命令

2.5.1.1、集合内

  • 添加成员
zadd key score member [score member ...]

下面操作向有序集合user:rank添加用户李四和他的score250:

127.0.0.1:6379> zadd user:ranking 250 李四
(integer) 1
  • 计算成员个数
zcard key
  • 计算某个成员的score
zscore key member
  • 计算成员的排名
zrank key member zrevrank key member
  • 删除成员
zrem key member [member ...]

2.5.1.2、集合间的操作

  • 交集
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
  • 并集
zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

2.5.2、应用场景

有序集合比较适合用于需要排行的地方。

2.5.2.1、用户点赞统计

可以用于统计博客、视频网站等作品的点赞数,可以根据点赞数对作品进行排行。

3、基本数据类型内部编码

通过上面的介绍,我们已经了解了五种基本数据结构,既然叫数据结构,那么一定是有内部的组成,就比如Java中的String由char或者byte数组组成。我们这里简单了解一下Redis五种基本数据结构的内部编码。

image.png

3.1、字符串

字符串类型的内部编码有3种:

  • int:8个字节的长整型。
  • embstr:小于等于39个字节的字符串。
  • raw:大于39个字节的字符串。

image.png

3.2、哈希

哈希类型的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries  配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64  字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。
  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

3.3、列表

列表类型的内部编码有两种。

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置  (默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时  (默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使 用。
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

3.4、集合

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-max- intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
  • hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。

3.5、有序集合

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-  entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist  可以有效减少内存的使用。
  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。

image.png

这里只是简单地了解一下,未来如果有机会,会再进一步学习Redis的实现来更深入地了解Redsi基本数据结构的内部原理。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
10天前
|
NoSQL 算法 Redis
docker高级篇(大厂进阶):安装redis集群
docker高级篇(大厂进阶):安装redis集群
62 24
|
3天前
|
NoSQL 关系型数据库 MySQL
Linux安装jdk、mysql、redis
Linux安装jdk、mysql、redis
67 7
|
24天前
|
存储 消息中间件 缓存
Redis 5 种基础数据结构?
Redis的五种基础数据结构——字符串、哈希、列表、集合和有序集合——提供了丰富的功能来满足各种应用需求。理解并灵活运用这些数据结构,可以极大地提高应用程序的性能和可扩展性。
28 2
|
1月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
43 5
|
1月前
|
NoSQL Linux PHP
如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤
本文介绍了如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤。接着,对比了两种常用的 PHP Redis 客户端扩展:PhpRedis 和 Predis,详细说明了它们的安装方法及优缺点。最后,提供了使用 PhpRedis 和 Predis 在 PHP 中连接 Redis 服务器及进行字符串、列表、集合和哈希等数据类型的基本操作示例。
66 4
|
1月前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
|
1月前
|
存储 SQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(1)作者——LJS[含MySQL的下载、安装、配置详解步骤及报错对应解决方法]
Mysql And Redis基础与进阶操作系列(1)之[MySQL的下载、安装、配置详解步骤及报错对应解决方法]
|
2月前
|
存储 消息中间件 NoSQL
Redis 数据结构与对象
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求和数据特点来选择合适的数据结构,并合理地设计数据模型,以充分发挥 Redis 的优势。
60 8
|
2月前
|
存储 NoSQL Java
介绍下Redis 的基础数据结构
本文介绍了Redis的基础数据结构,包括动态字符串(SDS)、链表和字典。SDS是Redis自实现的动态字符串,避免了C语言字符串的不足;链表实现了双向链表,提供了高效的操作;字典则类似于Java的HashMap,采用数组加链表的方式存储数据,并支持渐进式rehash,确保高并发下的性能。
介绍下Redis 的基础数据结构
|
2月前
|
NoSQL Ubuntu Linux
Redis 安装
10月更文挑战第14天
71 1

热门文章

最新文章