redis服务介绍
@
基础概念
Remote Dictionary Server(Redis)远程字典服务器是完全开源免费的,用C语言编写的,遵守BSD开源协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL(非关系型)数据库,它也通常被称为数据结构服务器,因为值(value)可以是字符串(String),哈希(Map),列表(list), 集合(sets)和有序集合(sorted sets)等类型。。
Redis的主要特点:
- 高性能:Redis通过将数据存储在内存中,提供了极快的读写速度。
- 多种数据类型:支持丰富的数据类型,如字符串、列表、集合、有序集合和哈希。
- 持久化:虽然Redis主要是内存数据库,但它提供了多种持久化选项,包括RDB快照和AOF(Append Only File)日志。
- 高可用性:通过主从复制和Redis Sentinel实现高可用性,确保数据的可靠性和服务的连续性。
- 分布式:支持Redis Cluster,允许数据分布在多个节点上,实现水平扩展。
常见应用场景:
- 缓存:由于其高性能,Redis常用于缓存层,加速应用的响应速度。
- 会话存储:许多网站使用Redis来存储用户会话信息。
- 排行榜和计数器:利用有序集合和其他数据结构,Redis可以方便地实现排行榜和计数器功能。
- 发布/订阅:Redis的发布/订阅功能可以用于实时消息传递。
- 队列:通过列表和集合,Redis可以实现高效的队列管理。
redis可以在特定应用场景下作为rabbimq和memcached的替代。
-
使用Redis而不是memcached来解决问题,不仅可以让代码变得更简短、更易懂、更易维护,而且还可以使代码的运行速度更快(因为用户不需要通过读取数据库来更新数据)。除此之外,在其他许多情况下,Redis的效率和易用性也比关系数据库要好得多。
-
什么数据会存到Redis数据库中?主要是热点数据,不会经常改变的,一般是常量。比如登录验证的Cookie,购物车,历史浏览记录。(只要具有一定时间的生命周期)比如首页的商品信息,一般不会变。比如秒杀的商品信息,一般也不会变。比如地图的经纬度信息,一般也不会变。
Redis作为高性能的内存开源数据库,其主要目的是解决以下几类问题:
- 1.高速缓存问题
场景:数据库查询速度慢,无法满足高并发场景下的快速请求需求。
:通过将常用的数据存储在内存中,Redis 提供极低的延迟(通常在微秒级别)来加速数据提升的读取和写入,从而显着解决系统性能。 - 2.高发问题
场景:传统关系型数据库在高并发的场景很容易成为系统瓶颈。
解决:Redis支持高并发访问,能够承载负载万到百万级的QPS(每秒请求数),非常适合在高并发场景中数据库作为或存储层使用。 - 3.数据结构特别
场景:某些应用需要支持复杂的数据结构,比如数组、排行榜、队列等。
解决:Redis提供丰富的数据结构支持,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、群体集合(Sorted Set)等,可以高效地解决这些场景需求。 - 4.分布式锁和任务队列
场景:多个系统中需要确保资源的独占访问,或者需要高效的管理任务队列。
解决:Redis 提供了简单且高效的分配SETNX和 Lua 脚本实现)和消息(通过列表或发布/订阅模式实现),用于协调和管理整个系统的资源。 - 5.持久化与数据恢复
场景:需要兼顾内存数据的性能和数据的持久化存储,防止意外宕机导致数据丢失。
解决:Redis提供了多种持久化机制(RDB快照、AOF日志),可以根据需要配置数据的存储策略,在性能和可靠性之间取得平衡。 - 6.实时分析和统计
场景:需要实时对数据进行高频统计和分析,比如访问统计、热点数据识别。
解决:Redis的内存操作极快,可以用于实时统计页面访问量、操作频次等,并结合其他数据结构(如位图、HyperLogLog)实现高效复杂的统计功能。 - 7.高可用和扩展性
场景:需要保证服务的稳定性和可扩展性,应对突发流量和节点故障。
解决:Redis提供了主从复制(Replication)、哨兵模式(Sentinel)和集群模式(Cluster),支持高可用和多元化扩展,保证系统的可用性和扩展能力。
安装使用
ubuntu2404环境
apt install -y redis
systemctl enable --now redis-server
redis数据库不区分大小写,并且输入命令会有提示!!
基础操作命令
连接到Redis服务器:
redis-cli -h 127.0.0.1 -p 6379
root@huhy:~# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379>
字符串
设置键值对并获取:key是键,huhy就是值对
127.0.0.1:6379> set key "huhy"
OK
127.0.0.1:6379> get key
"huhy"
127.0.0.1:6379>
删除值对;
127.0.0.1:6379> del key
(integer) 1
127.0.0.1:6379> get key
(nil)
查看所有键:,*表示所有
127.0.0.1:6379> keys *
(empty array)
数据类型操作命令
列表
设置键值及过期时间:10是秒为单位,十秒后mykey就会消失,内容为空
127.0.0.1:6379> setex mykey 10 "setkey"
OK
127.0.0.1:6379> get mykey
"setkey"
127.0.0.1:6379>
获取键的剩余生存时间:
127.0.0.1:6379> setex hu 20 "test"
OK
127.0.0.1:6379> ttl hu
(integer) 11
127.0.0.1:6379> ttl hu
(integer) 8
127.0.0.1:6379> ttl hu
(integer) 6
127.0.0.1:6379> ttl hu
(integer) 5
127.0.0.1:6379>
追加值到键:如果追加到设置有过期的键中可能会导致过期时间失效
127.0.0.1:6379> get hu
"hy"
127.0.0.1:6379> append hu "hy"
(integer) 4
127.0.0.1:6379> get hu
"hyhy"
127.0.0.1:6379>
左侧推入元素:从而形成一个列表
127.0.0.1:6379> lpush mylist "test1"
(integer) 1
127.0.0.1:6379> lpush mylist "test2"
(integer) 2
127.0.0.1:6379> lpush mylist "test3"
(integer) 3
查看列表中的元素:可以理解成test1是第一个,从左边推入一个元素后,就变成了第二个
127.0.0.1:6379> lrange mylist 0 -1
1) "test3"
2) "test2"
3) "test1"
获取列表长度:
127.0.0.1:6379> llen mylist
(integer) 3
127.0.0.1:6379>
右侧推出元素:从而删除列表中的一个元素
127.0.0.1:6379> rpop mylist
"test1"
127.0.0.1:6379> rpop mylist
"test2"
127.0.0.1:6379> rpop mylist
"test3"
127.0.0.1:6379> rpop mylist
(nil)
127.0.0.1:6379>
集合
添加元素到集合:
127.0.0.1:6379> sadd jihe "member1"
(integer) 1
获取集合所有成员:
127.0.0.1:6379> smembers jihe
1) "member1"
127.0.0.1:6379>
管理和维护命令
查看数据库信息:
127.0.0.1:6379> info
查看连接客户端列表:
127.0.0.1:6379> client list
id=3 addr=127.0.0.1:38112 laddr=127.0.0.1:6379 fd=8 name= age=3098 idle=0 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=20448 argv-mem=10 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=22298 events=r cmd=client|list user=default redir=-1 resp=2
127.0.0.1:6379>
清空当前数据库:
127.0.0.1:6379> flushdb
OK
清空所有数据库:
127.0.0.1:6379> flushall
OK
保存数据到磁盘:
127.0.0.1:6379> save
OK
后台异步保存数据到磁盘:
127.0.0.1:6379> bgsave
Background saving started
查看Redis服务器配置:
127.0.0.1:6379> config get parameter
(empty array)
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379>
配置一主二从集群
在一主二从架构中,包含一个主节点(Master)和两个从节点(Slave)。
- 主节点(Master):它负责接收客户端的读写请求,是数据写入的源头,对数据进行更新等操作,并且会将自身的数据变更信息传递给从节点,以此来保证数据的一致性。例如,当有新的数据被写入到主节点中时,后续它会通知从节点进行相应的数据更新。
- 从节点(Slave):主要作用是复制主节点的数据,它们会定期从主节点获取数据更新的内容,并应用到自身的数据集上,从而保持和主节点的数据同步。从节点通常只负责处理读请求,分担主节点的读压力,通过这种方式可以提高整个系统的读性能以及可用性。在有两个从节点的情况下,能更好地分摊读负载,满足更多的读操作需求。
工作原理
- 建立连接:从节点启动后,会主动向主节点发起连接请求,建立起通信链路,便于后续的数据同步等交互操作。
数据同步: - 首次同步时,从节点会向主节点发送 PSYNC 命令(在旧版本中是 SYNC 命令),主节点接收到命令后,会开始执行 BGSAVE 命令生成 RDB 文件(Redis 的一种数据持久化文件格式),并在生成过程中把期间接收到的写命令缓存起来。
- 当 RDB 文件生成完毕后,主节点会将其发送给从节点,从节点接收后会进行加载,把数据恢复到自身内存中。之后主节点再将缓存的写命令发送给从节点执行,这样就完成了首次的数据同步,使得从节点的数据与主节点初始状态保持一致。
- 在首次同步完成后,主节点后续每执行一个写命令,都会以异步的方式将写命令发送给从节点,从节点接收到命令后会在本地执行,从而持续保持数据同步,时刻让自身的数据与主节点一致。
节点信息:Ubuntu2404
| 主机名 | IP |
|---|---|
| redis1 (主) | 192.168.200.160 |
| redis2(从) | 192.168.200.161 |
| redis3(从) | 192.168.200.163 |
三台节点初始化环境
vi init.sh
#!/bin/bash
# 定义节点信息
NODES=("192.168.200.160 redis1 root" "192.168.200.161 redis2 root" "192.168.200.162 redis3 root")
# 定义当前节点的密码(默认集群统一密码)
HOST_PASS="000000"
# 时间同步的目标节点
TIME_SERVER=redis1
# 时间同步的地址段
TIME_SERVER_IP=192.160.200.0/24
# 欢迎界面
cat > /etc/motd <<EOF
################################
# Welcome to redis #
################################
EOF
# 修改主机名
for node in "${NODES[@]}"; do
ip=$(echo "$node" | awk '{print $1}')
hostname=$(echo "$node" | awk '{print $2}')
# 获取当前节点的主机名和 IP
current_ip=$(hostname -I | awk '{print $1}')
current_hostname=$(hostname)
# 检查当前节点与要修改的节点信息是否匹配
if [[ "$current_ip" == "$ip" && "$current_hostname" != "$hostname" ]]; then
echo "Updating hostname to $hostname on $current_ip..."
hostnamectl set-hostname "$hostname"
if [ $? -eq 0 ]; then
echo "Hostname updated successfully."
else
echo "Failed to update hostname."
fi
break
fi
done
# 遍历节点信息并添加到 hosts 文件
for node in "${NODES[@]}"; do
ip=$(echo "$node" | awk '{print $1}')
hostname=$(echo "$node" | awk '{print $2}')
# 检查 hosts 文件中是否已存在相应的解析
if grep -q "$ip $hostname" /etc/hosts; then
echo "Host entry for $hostname already exists in /etc/hosts."
else
# 添加节点的解析条目到 hosts 文件
sudo sh -c "echo '$ip $hostname' >> /etc/hosts"
echo "Added host entry for $hostname in /etc/hosts."
fi
done
if [[ ! -s ~/.ssh/id_rsa.pub ]]; then
ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa -q -b 2048
fi
# 检查并安装 sshpass 工具
if ! which sshpass &> /dev/null; then
echo "sshpass 工具未安装,正在安装 sshpass..."
sudo apt-get install -y sshpass
fi
# 遍历所有节点进行免密操作
for node in "${NODES[@]}"; do
ip=$(echo "$node" | awk '{print $1}')
hostname=$(echo "$node" | awk '{print $2}')
user=$(echo "$node" | awk '{print $3}')
# 使用 sshpass 提供密码,并自动确认密钥
sshpass -p "$HOST_PASS" ssh-copy-id -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub "$user@$hostname"
done
# 时间同步
apt install -y chrony
if [[ $TIME_SERVER_IP == *$(hostname -I)* ]]; then
# 配置当前节点为时间同步源
sed -i '20,23s/^/#/g' /etc/chrony/chrony.conf
echo "server $TIME_SERVER iburst maxsources 2" >> /etc/chrony/chrony.conf
echo "allow $TIME_SERVER_IP" >> /etc/chrony/chrony.conf
echo "local stratum 10" >> /etc/chrony/chrony.conf
else
# 配置当前节点同步到目标节点
sed -i '20,23s/^/#/g' /etc/chrony/chrony.conf
echo "pool $TIME_SERVER iburst maxsources 2" >> /etc/chrony/chrony.conf
fi
# 重启并启用 chrony 服务
systemctl restart chronyd
systemctl enable chrony
echo "###############################################################"
echo "################# 集群初始化成功 #####################"
echo "###############################################################"
bash init.sh
- 安装软件包
apt install -y redis
systemctl restart redis
配置redis1文件
vi /etc/redis/redis.conf
#注释
#bind 127.0.0.1 -::1
#修改关闭保护
protected-mode no
#添加
requirepass "000000"
#添加
masterauth "000000"
#修改开启AOF持久化
appendonly yes
重启redis1节点服务
systemctl restart redis
配置redis2文件
root@redis1:~# scp /etc/redis/redis.conf redis2:/etc/redis/redis.conf
redis.conf 100% 104KB 18.4MB/s 00:00
root@redis1:~# scp /etc/redis/redis.conf redis3:/etc/redis/redis.conf
redis.conf
vi /etc/redis/redis.conf
#添加主节点信息
replicaof 192.168.200.160 6379
重启redis2节点服务
systemctl restart redis
配置redis3文件
scp /etc/redis/redis.conf redis3:/etc/redis/redis.conf
重启redis3节点服务
systemctl restart redis
主节点验证
root@redis1:~# redis-cli -h 192.168.200.160 -p 6379 -a 000000 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.200.161,port=6379,state=online,offset=14,lag=0
slave1:ip=192.168.200.162,port=6379,state=online,offset=14,lag=1
master_failover_state:no-failover
master_replid:19972c43e4830f38f594806bc26b3443f2568c74
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
root@redis1:~#
redis2节点
root@redis2:~# redis-cli -h 192.168.200.161 -p 6379 -a 000000 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:192.168.200.160
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_read_repl_offset:70
slave_repl_offset:70
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:19972c43e4830f38f594806bc26b3443f2568c74
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70
root@redis2:~#
redis3节点
root@redis3:~# redis-cli -h 192.168.200.162 -p 6379 -a 000000 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:192.168.200.160
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:126
slave_repl_offset:126
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:19972c43e4830f38f594806bc26b3443f2568c74
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:126
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:126

Remote Dictionary Server(Redis)远程字典服务器是完全开源免费的,用C语言编写的,遵守BSD开源协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL(非关系型)数据库,它也通常被称为数据结构服务器,因为值(value)可以是字符串(String),哈希(Map),列表(list), 集合(sets)和有序集合(sorted sets)等类型。
浙公网安备 33010602011771号