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
posted @ 2024-06-27 22:35  huhy  阅读(37)  评论(0)    收藏  举报  来源
--> --> /*文章评论*/