你一定想知道的Redis数据库详解

2024-08-29 19:52

本文主要是介绍你一定想知道的Redis数据库详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、Redis介绍

1.1定义

1.2为什么要有Redis

1.3 Redis和Mysql的对比

1.4 Redis的一些常见命令

二、Redis 常见的数据结构

一、字符串(String)

二、哈希(Hash)

三、列表(List)

四、集合(Set)

五、有序集合(Sorted Set)

三、Redis的应用场景

四、实验练习

4.1redis部署

实验环境:

实验步骤:

1.源码安装

2.启动

3.解决报错问题

4.再次启动,查看

5.配置redis

4.2 redis主从复制

实验环境:

实验步骤:

1.修改mastser点的配置文件

2.配置slave节点

3.测试

4.3哨兵模式(高可用)

实验环境:

实验步骤:

1.备份一份配置文件

2.在master:node1节点中

3.启动服务

4.测试

4.4部署redis cluster

实验环境:

实验步骤:

1.添加认证和密码

2.部署集群

3.检测redis集群状态

4.5 集群扩容

实验环境:

实验步骤:

1.添加master

2.分配槽位

3.添加salve

4.查看

4.6集群的维护 

实验环境:

实验步骤:

1.删除150,50

2.移除要下线主机的哈希槽位

3.检查50有没有数据

4.没有,则删除 


一、Redis介绍

1.1定义

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

1.2为什么要有Redis

一、高性能的数据存储与访问

  1. 内存存储

    • Redis 将数据存储在内存中,这使得它能够以极快的速度进行数据读写操作。与传统的基于磁盘存储的数据库相比,Redis 可以在毫秒甚至微秒级别响应请求,极大地提高了系统的响应速度。例如,在高并发的 Web 应用中,对于频繁访问的热点数据,如用户会话信息、商品库存等,存储在 Redis 中可以快速获取,避免了频繁地从磁盘读取数据带来的延迟。
    • 对于需要实时处理大量数据的场景,如金融交易系统、实时数据分析平台等,Redis 的高性能内存存储能够满足对数据处理速度的严格要求。
  2. 高效的数据结构

    • Redis 提供了丰富的数据结构,如字符串、哈希表、列表、集合、有序集合等。这些数据结构针对不同的应用场景进行了优化,使得开发者可以根据具体需求选择最合适的数据结构来存储和操作数据。
    • 例如,使用哈希表可以方便地存储对象属性,快速获取和修改特定属性的值;列表可以用于实现消息队列、栈等数据结构;集合和有序集合则适用于实现去重、排行榜等功能。

二、数据缓存

  1. 减轻数据库压力

    • 在很多应用中,数据库往往是系统的性能瓶颈。通过将频繁访问的数据缓存到 Redis 中,可以减少对数据库的访问次数,从而降低数据库的负载。例如,在电商系统中,商品详情页的访问量非常大,如果每次都从数据库中读取商品信息,会给数据库带来巨大的压力。而将商品信息缓存到 Redis 中,大部分请求可以直接从 Redis 中获取数据,只有在数据发生变化时才更新缓存和数据库,这样可以显著提高系统的性能和稳定性。
    • 对于一些复杂的查询结果,也可以缓存到 Redis 中,避免重复执行复杂的数据库查询操作。
  2. 提高响应速度

    • 由于 Redis 的高速读写特性,从缓存中获取数据比从数据库中获取数据要快得多。这可以大大缩短用户的等待时间,提高用户体验。例如,在社交网络应用中,用户的好友列表、动态消息等可以缓存到 Redis 中,当用户刷新页面时,可以快速获取这些数据,而无需等待数据库查询的完成。

三、分布式锁

  1. 保证数据一致性

    • 在分布式系统中,多个节点可能同时对共享资源进行访问和修改,这可能导致数据不一致的问题。Redis 可以实现分布式锁,确保在同一时间只有一个节点能够对共享资源进行操作。例如,在电商系统中,当多个用户同时抢购一件商品时,需要使用分布式锁来保证商品库存的正确扣减,避免超卖现象的发生。
    • 分布式锁可以通过 Redis 的 SETNX(SET if Not eXists)命令来实现。当一个节点尝试获取锁时,它会使用 SETNX 命令在 Redis 中设置一个特定的键值对。如果设置成功,说明该节点获取到了锁;如果设置失败,则说明锁已经被其他节点持有,该节点需要等待锁释放后再尝试获取。
  2. 提高系统可靠性

    • 分布式锁还可以用于保证分布式任务的正确执行顺序。例如,在分布式任务调度系统中,多个任务可能需要按照特定的顺序执行。通过使用分布式锁,可以确保每个任务在执行前先获取到相应的锁,从而保证任务的执行顺序正确,避免因任务执行顺序混乱而导致的系统故障。

四、消息队列

  1. 异步处理

    • Redis 的列表数据结构可以用作简单的消息队列。生产者可以将消息推入列表的一端,消费者可以从列表的另一端取出消息进行处理。这种方式可以实现异步处理,将耗时的操作从主线程中分离出来,提高系统的响应速度和吞吐量。
    • 例如,在用户注册场景中,当用户提交注册信息后,系统可以将注册成功的消息推入 Redis 队列,然后由后台的异步任务从队列中取出消息,发送欢迎邮件、初始化用户数据等操作。这样可以避免用户在注册过程中等待这些耗时操作的完成,提高用户体验。
  2. 任务分发

    • Redis 消息队列还可以用于任务分发。在分布式系统中,可以将任务分配给不同的节点进行处理。生产者将任务推入 Redis 队列,各个节点作为消费者从队列中获取任务并进行处理。这种方式可以实现任务的动态分配和负载均衡,提高系统的处理能力和可靠性。
    • 例如,在图片处理系统中,可以将图片处理任务推入 Redis 队列,各个处理节点从队列中获取任务,对图片进行压缩、裁剪等操作。这样可以根据系统的负载情况动态调整处理节点的数量,提高系统的处理效率。

五、数据持久化

  1. 防止数据丢失

    • 虽然 Redis 将数据存储在内存中,但它也提供了数据持久化的功能,以防止数据因系统故障而丢失。Redis 支持两种持久化方式:RDB(Redis Database)和 AOF(Append Only File)。
    • RDB 持久化是通过将内存中的数据快照保存到磁盘文件中来实现的。可以定期执行 RDB 持久化操作,将当前内存中的数据保存到磁盘上。在系统启动时,可以从 RDB 文件中恢复数据。
    • AOF 持久化则是将 Redis 执行的所有写命令记录到一个追加文件中。在系统启动时,可以重新执行 AOF 文件中的写命令来恢复数据。
  2. 数据备份与恢复

    • 数据持久化还可以用于数据备份和恢复。可以定期将 Redis 的数据备份到其他存储设备上,如远程服务器、云存储等。在系统发生故障时,可以从备份中恢复数据,保证数据的安全性和可靠性。

六、其他优势

  1. 支持主从复制

    • Redis 支持主从复制功能,可以将数据从一个 Redis 实例复制到多个从实例上。主从复制可以实现数据的冗余备份,提高系统的可靠性。同时,从实例可以分担主实例的读负载,提高系统的读性能。
    • 在主从复制架构中,主实例负责接收写请求,并将写操作同步到从实例上。从实例只负责处理读请求,从而减轻主实例的负载。如果主实例发生故障,可以将一个从实例提升为主实例,继续提供服务,实现高可用。
  2. 简单易用

    • Redis 的命令简洁明了,易于学习和使用。它提供了丰富的客户端库,支持多种编程语言,使得开发者可以方便地在自己的项目中集成 Redis。
    • 此外,Redis 的配置相对简单,不需要复杂的安装和部署过程。它可以在各种操作系统上运行,并且可以根据实际需求进行灵活的配置和扩展。

1.3 Redis和Mysql的对比

对比项目RedisMySQL
数据存储介质内存为主,可配置持久化到磁盘磁盘
数据类型丰富的数据结构如字符串、哈希、列表、集合、有序集合等关系型数据,以表结构存储
性能读写速度极快,通常在毫秒甚至微秒级别相对较慢,尤其是在处理大量复杂查询时
适用场景适合缓存热点数据、实现分布式锁、作为消息队列等适合存储持久化的、结构化的业务数据
数据持久性可配置持久化,但相比 MySQL 持久性稍弱数据持久性强,通过事务等机制保证数据完整性
可扩展性支持主从复制、集群等,扩展性较好也可通过主从复制、分库分表等方式扩展,但相对复杂
数据一致性在某些配置下保证强一致性较难,更注重性能通过事务等机制保证强一致性
查询语言简单的命令式操作SQL 语言,功能强大但相对复杂

1.4 Redis的一些常见命令

命令作用例子
SET设置键值对SET key value,如 SET name "Tom" 设置键为 name,值为 "Tom"
GET获取键对应的值GET name,获取键 name 对应的值,如果之前设置了 name 为 "Tom",则返回 "Tom"
DEL删除键DEL key,如 DEL name 删除键 name
EXISTS判断键是否存在EXISTS key,如 EXISTS name 判断键 name 是否存在
INCR将键的值自增 1INCR counter,假设键 counter 初始值为 0,执行后变为 1
DECR将键的值自减 1DECR counter,若 counter 为 1,执行后变为 0
LPUSH将一个或多个值插入到列表的左端LPUSH listItem "item1" "item2",向名为 listItem 的列表左边插入 "item1" 和 "item2"
RPUSH将一个或多个值插入到列表的右端RPUSH listItem "item3",向名为 listItem 的列表右边插入 "item3"
LRANGE获取列表指定范围内的元素LRANGE listItem 0 -1,获取名为 listItem 的列表的所有元素
HSET将哈希表 key 中的域 field 的值设为 valueHSET userInfo name "Alice",在名为 userInfo 的哈希表中设置域 name 的值为 "Alice"
HGET获取哈希表 key 中给定域 field 的值HGET userInfo name,获取名为 userInfo 的哈希表中域 name 的值
SADD将一个或多个 member 元素加入到集合 key 当中SADD setItem "element1" "element2",向名为 setItem 的集合中加入元素 "element1" 和 "element2"
SMEMBERS返回集合 key 中的所有成员SMEMBERS setItem,返回名为 setItem 的集合中的所有元素
ZADD将一个或多个 member 元素及其 score 值加入到有序集合 key 当中ZADD sortedSet 10 "member1" 20 "member2",向名为 sortedSet 的有序集合中加入元素 "member1" 和 "member2" 及其对应的分数
ZRANGE返回有序集合 key 中,指定区间内的成员ZRANGE sortedSet 0 -1,返回名为 sortedSet 的有序集合中的所有元素

二、Redis 常见的数据结构

一、字符串(String)

这是最基本的数据结构,可以存储二进制安全的字符串,包括文本、序列化对象等。

  • 用途:
    • 缓存用户信息、商品信息等简单的键值对数据。例如,存储用户的登录状态信息,将用户 ID 作为键,存储包含用户登录状态、最后登录时间等信息的字符串作为值。
    • 计数器。可以用于统计网站的访问次数、用户的操作次数等。例如,每次有用户访问网站时,使用 INCR 命令对特定的访问计数器键进行自增操作。

二、哈希(Hash)

哈希是一个键值对集合,它是字符串字段和字符串值之间的映射。

  • 用途:
    • 存储对象信息。比如存储用户对象,可以将用户 ID 作为哈希的键,字段可以包括用户名、年龄、性别等属性,每个字段对应的值就是具体的属性值。这样可以方便地对单个用户的属性进行操作,而无需在数据库中进行复杂的查询。
    • 存储配置信息。可以将不同的配置项作为哈希的字段,方便进行配置的读取和修改。

三、列表(List)

列表是一个简单的字符串列表,按照插入顺序排序。

  • 用途:
    • 消息队列。生产者可以使用 LPUSH 命令将消息插入列表的左端,消费者使用 RPOP 命令从列表的右端取出消息进行处理。例如,在分布式任务系统中,任务生成器将任务描述作为消息推入列表,各个任务执行节点从列表中获取任务并执行。
    • 栈和队列。可以通过 LPUSH 和 LPOP 实现栈的功能,先入后出;通过 LPUSH 和 RPOP 实现队列的功能,先入先出。

四、集合(Set)

集合是无序的、唯一的字符串集合。

  • 用途:
    • 去重。可以用于存储不重复的元素,比如存储用户的 ID,确保每个用户在集合中只出现一次。在用户签到系统中,可以使用集合来记录每天签到的用户,方便统计签到用户的数量和进行用户去重。
    • 交集、并集和差集运算。可以用于找出不同集合之间的共同元素、合并元素或者找出不同元素。例如,在社交网络中,可以使用集合来存储用户的关注列表和粉丝列表,通过交集运算可以找出共同关注的用户,通过差集运算可以找出单向关注的用户。

五、有序集合(Sorted Set)

有序集合是每个元素都关联一个分数(score)的集合,元素按照分数从小到大排列。

  • 用途:
    • 排行榜。可以根据元素的分数进行排序,比如游戏中的得分排行榜、商品的销量排行榜等。每个玩家的游戏得分作为元素的分数,玩家 ID 作为元素存储在有序集合中,通过 ZRANGE 命令可以获取排行榜的前几名。
    • 范围查询。可以根据分数范围查询元素,比如查询得分在一定范围内的玩家。在实时数据处理中,可以使用有序集合存储时间戳作为分数,数据作为元素,方便进行基于时间范围的查询。

三、Redis的应用场景

一、缓存

  • 页面缓存:存储不常变化的页面内容,减少数据库访问压力,提高响应速度。如电商网站的商品分类页面等。
  • 数据缓存:缓存频繁访问的数据,如用户信息、商品详情等,提高访问效率。

二、计数器和限速器

  • 计数器:可实现网站访问次数、用户操作次数等统计。例如统计网站每日访问量。
  • 限速器:限制用户在一定时间内的请求次数,防止过度请求。

三、分布式锁

  • 确保分布式系统中同一时间只有一个节点能操作共享资源,避免数据不一致。如电商抢购防止超卖。
  • 保证分布式任务调度中任务执行顺序正确。

四、消息队列

  • 异步处理:将耗时操作分离出来,提高系统响应速度和吞吐量。如用户注册后异步发送欢迎邮件。
  • 任务分发:实现任务动态分配和负载均衡。如图片处理系统分配任务。

五、排行榜

  • 游戏排行榜:根据玩家得分进行排名。
  • 商品销量排行榜:方便用户查看畅销商品,商家调整营销策略。

六、会话存储

  • 在分布式 Web 服务器架构中存储用户会话信息,实现快速访问和分布式存储。

七、地理位置服务

  • 存储用户地理位置信息,进行附近商家推荐、用户查找等操作。如外卖配送系统分配订单。

四、实验练习

4.1redis部署

实验环境:

红帽九主机。

实验步骤:

1.源码安装

官网下载解压:

安装依赖项:

 编译:

2.启动

3.解决报错问题
[root@redis-node1 utils]# vim install_server.sh 
#bail if this system is managed by systemd
#_pid_1_exe="$(readlink -f /proc/1/exe)"
#if [ "${_pid_1_exe##*/}" = systemd ]
#then
# echo "This systems seems to use systemd."
# echo "Please take a look at the provided example service unit files in
this directory, and adapt and install them. Sorry!"
# exit 1
#fi

4.再次启动,查看

一直回车选默认的就行

5.配置redis
[root@redis-node1 utils]# vim /etc/redis/6379.conf
bind * -::*

4.2 redis主从复制

实验环境:

红帽九主机

实验步骤:

1.修改mastser点的配置文件
[root@redis-node1 ~]# vim /etc/redis/6379.confprotected-mode no#node2,node3都要关

2.配置slave节点
[root@redis-node2 ~]# vim /etc/redis/6379.confreplicaof 172.25.254.100 6379
#node3也同样操作

3.测试

4.3哨兵模式(高可用)

实验环境:

红帽九主机

实验步骤:

1.备份一份配置文件

所有主机都要做:

2.在master:node1节点中

编辑配置文件:

[root@redis-node1 ~]# cd redis-7.4.0/
[root@redis-node1 redis-7.4.0]# cp sentinel.conf /etc/redis/
[root@redis-node1 redis-7.4.0]# vim /etc/redis/sentinel.conf
protected-mode no #关闭保护模式port 26379 #监听端口daemonize no #进入不打如后台pidfile /var/run/redis-sentinel.pid #sentinel进程pid文件loglevel notice #日志级别sentinel monitor mymaster 172.25.254.100 6379 2 #创建sentinel监控监控master主机,2表示必须得到2票sentinel down-after-milliseconds mymaster 10000 #master中断时长,10秒连不上视为sentinel parallel-syncs mymaster 1 #发生故障转移后,同时开始同步新sentinel failover-timeout mymaster 180000 #整个故障切换的超时时间为3分钟

复制配置文件到其他主机:

3.启动服务

所有主机都要启动:

4.测试

再开一个node1窗口,讲redis服务停掉,模拟下线:
这是哨兵模式会监控,十秒后,node2,node3会提示node1下线,达到两票,则会重新选取新的主,下面这里选取的30为新的主

连到node3查看是否为主:

node1恢复后会变成slave:

4.4部署redis cluster

实验环境:

需要六台红帽9,构建三主三从的架构。

实验步骤:

1.添加认证和密码
[root@redis-node1 ~]# vim /etc/redis/redis.conf
masterauth "123456" 
requirepass "123456"
cluster-enabled yes 
cluster-config-file nodes-6379.conf 
cluster-node-timeout 15000 root@redis-node1 ~]# systemctl enable --now redis

其余主机使用scp传输过去。

2.部署集群

3.检测redis集群状态
[root@redis-node1 ~]# redis-cli -a 123456 -- cluster info 172.25.254. 10: 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not b
e safe.
172.25.254.11:6379 (0492aeca ... ) -> 0 keys | 5461 slots | 1 slaves.
172.25.254.30:6379 (a1lab250. .. ) -> 0 keys | 5461 slots | 1 slaves.

4.5 集群扩容

实验环境:

相同。

实验步骤:

1.添加master

再准备两台虚拟机,IP为172.25.254.(50,150)并将其添加到集群里。

[root@redis-master1 ~]# redis-cli -a 123456 --cluster info 172.25.254.10:6379              
Warning: Using a password with '-a' or '-u' option on the command line interface 
may not be safe.
172.25.254.11:6379 (5ab2e93f...) -> 0 keys | 5461 slots | 1 slaves.
172.25.254.50:6379 (009571cb...) -> 0 keys | 0 slots | 0 slaves.
172.25.254.21:6379 (ba504e78...) -> 1 keys | 5462 slots | 1 slaves.
172.25.254.31:6379 (1fcaeb1d...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.

2.分配槽位

3.添加salve
[root@redis-master1 ~]# redis-cli -a 123456 --cluster add-node 
172.25.254.150:6379 172.25.254.11:6379 --cluster-slave --cluster-master-id 
009571cb206a89afa6658b60b2d403136056ac09

4.查看

4.6集群的维护 

实验环境:

相同。

实验步骤:

1.删除150,50

2.移除要下线主机的哈希槽位

3.检查50有没有数据

4.没有,则删除 

这篇关于你一定想知道的Redis数据库详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118740

相关文章

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

mysql数据库分区的使用

《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

mac中资源库在哪? macOS资源库文件夹详解

《mac中资源库在哪?macOS资源库文件夹详解》经常使用Mac电脑的用户会发现,找不到Mac电脑的资源库,我们怎么打开资源库并使用呢?下面我们就来看看macOS资源库文件夹详解... 在 MACOS 系统中,「资源库」文件夹是用来存放操作系统和 App 设置的核心位置。虽然平时我们很少直接跟它打交道,但了

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

Rust 数据类型详解

《Rust数据类型详解》本文介绍了Rust编程语言中的标量类型和复合类型,标量类型包括整数、浮点数、布尔和字符,而复合类型则包括元组和数组,标量类型用于表示单个值,具有不同的表示和范围,本文介绍的非... 目录一、标量类型(Scalar Types)1. 整数类型(Integer Types)1.1 整数字

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,