企业级NoSql数据库Redis集群

知识点

一、关系型数据库和 NoSQL 数据库

1:数据库主要分为两大类:

关系型数据库与 NoSQL 数据库
关系型数据库 ,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库 中的数据主流的 MySQL Oracle MS SQL Server DB2 都属于这类传统数据库。
NoSQL 数据库 ,全称为 Not Only SQL ,意思就是适用关系型数据库的时候就使用关系型数据库,不适 用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为临时性键值存储(memcached Redis )、永久性键值存储( ROMA Redis )、面向文档的数据库 (MongoDB CouchDB )、面向列的数据库( Cassandra HBase ),每种 NoSQL 都有其特有的使用场景及优点。

2:为什么还要用 NoSQL 数据库呢

      主要是由于随着互联网发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天
性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。这样既有单机单库瓶颈,却又扩展困难,自
然无法满足日益增长的海量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,
NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高

3:RDBMSNOSQL的特点及优缺点

二、Remote Dictionary Server 简介

1:Redis特性

  • 速度快: 10W QPS,基于内存,C语言实现
  • 单线程
  • 持久化
  • 支持多种数据结构
  • 支持多种编程语言
  • 功能丰富: 支持Lua脚本,发布订阅,事务,pipeline等功能
  • 简单: 代码短小精悍(单机核心代码只有23000行左右),单线程开发容易,不依赖外部库,使用简单
  • 主从复制
  • 支持高可用和分布式

单线程为何如此快 ?
  • 纯内存
  • 非阻塞
  • 避免线程切换和竞态消耗

2:Redis应用场景

  • Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享
  • 缓存:数据查询、电商网站商品信息、新闻内容
  • 计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
  • 微博/微信社交场合:共同好友,粉丝数,关注,点赞评论等
  • 消息队列:ELK的日志缓存、部分业务的订阅发布系统
  • 地理位置: 基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能

3:缓存的实现流程

数据更新操作流程
数据读操作流程

三、Redis的安装

官方下载地址: http://download.redis.io/releases/

1、rpm包方式安装

2:源码安装

Warning
在一台主机中不能即用 rpm 安装也用源码安装

# 查看信息
[root@redis-node1 utils]# redis-cli
127.0.0.1:6379> info

四、Redis的基本操作

# 查看配置
127 .0.0.1:6379[1]> CONFIG GET bind
1 ) "bind"
2 ) "* -::*"
127 .0.0.1:6379[1]> CONFIG GET *
# 写入和读取数据
127 .0.0.1:6379> SET name lee
OK
127 .0.0.1:6379> GET name
"lee"
127 .0.0.1:6379> set name lee ex 5
OK
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> get name
(nil)
# 如果没有设定数据过期时间会一直存在, /var/lib/redis/6379/dump.rdb 内存快照中
127 .0.0.1:6379> set name lee
OK
127 .0.0.1:6379> KEYS * # 查看所有 key
1 ) "name"
# 选择数据库 redisa 中有 0-15 个数据库
127 .0.0.1:6379> select 1
OK
127 .0.0.1:6379[1]> get name
(nil)
127 .0.0.1:6379> select 0
127 .0.0.1:6379[1]> select 16
(error) ERR DB index is out of range
# 移动数据
127 .0.0.1:6379> set name lee
OK
127 .0.0.1:6379> MOVE name 1
(integer) 1
127 .0.0.1:6379> GET name
(nil)
127 .0.0.1:6379> select 1
OK
127 .0.0.1:6379[1]> get name
"lee"
# 改变键名
127 .0.0.1:6379[1]> RENAME name id
OK
127 .0.0.1:6379[1]> get name
(nil)
127 .0.0.1:6379[1]> get id
"lee"
# 设定数据过期时间
127 .0.0.1:6379> set name lee ex 10000
OK
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> EXPIRE name 3
(integer) 1
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> get name
(nil)
# 删除
127 .0.0.1:6379> set name lee
OK
127 .0.0.1:6379> get name
"lee"
127 .0.0.1:6379> del name
(integer) 1
127 .0.0.1:6379> get name
(nil)
# 持久化保存
127 .0.0.1:6379> PERSIST name
(integer) 0
# 判断 key 是否存在
127 .0.0.1:6379> EXISTS name
(integer) 1
127 .0.0.1:6379> EXISTS lee
(integer) 0
# 清空当前库
127 .0.0.1:6379> flushdb
OK
127 .0.0.1:6379> GET name
(nil)
# 清空所有库
127 .0.0.1:6379[1]> FLUSHALL
OK

五、Redis 主从复制

1:环境配置

redis-node1 master
redis-node2 slave
redis-node3 slave
Note
在配置多台 redis 时建议用复制的方式节省编译时间

2:配置主从同步

1)修改mastser节点的配置文件
[root@redis-node1 & node2 & node3 ~] # vim /etc/redis/6379.conf
protected-mode no # 关闭 protected 模式
[root@redis-node1 &node2 & node3 ~] # /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
2)配置slave节点
[root@redis-node2 & 3 ~] # vim /etc/redis/6379.conf
replicaof 172 .25.254.100 6379
[root@redis-node2 & 3 ~] # /etc/init.d/redis_6379 restart
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
3) 测试效果
# mastser 节点
[root@redis-node1 ~] # redis-cli
127 .0.0.1:6379> set name lee
OK
# slave 节点查看
[root@redis-node2 ~] # redis-cli
127 .0.0.1:6379> get name
"lee"

3:主从同步过程

  • slave节点发送同步亲求到master节点
  • slave节点通过master节点的认证开始进行同步
  • master节点会开启bgsave进程发送内存rbdslave节点,在此过程中是异步操作,也就是说
  • master节点仍然可以进行写入动作
  • slave节点收到rdb后首先清空自己的所有数据
  • slave节点加载rdb并进行数据恢复
  • masterslave同步过程中master还会开启新的bgsave进程把没有同步的数据进行缓存
  • 然后通过自有的replactionfeedslave函数把未通过内存快照发动到slave的数据一条一条写入到 slave

六、Redis的哨兵(高可用)

实验环境: 我们用主两从来实现 Redis 的高可用架构

1:Redis哨兵

sentinel 中的三个定时任务
  • 10秒每个sentinelmasterslave执行info
  • 发现slave节点
  • 确认主从关系
  • 2秒每个sentinel通过master节点的channel交换信息(pub/sub)
  • 通过sentinel__:hello频道交互
  • 交互对节点的看法和自身信息
  • 1秒每个sentinel对其他sentinelredis执行pi

2:哨兵的实验过程

在所有阶段中关闭 protected-mode no
1)在master节点中

2)启动服务

Warning
        /etc/redis/sentinel.conf 文件在用哨兵程序调用后会更改其配置文件,如果需要重新做需要删掉文件重新编辑
3)测试

3. 在整个架构中可能会出现的问题

问题:
在生产环境中如果 master slave 中的网络出现故障,由于哨兵的存在会把 master 提出去
当网络恢复后, master 发现环境发生改变, master 就会把自己的身份转换成 slave
master 变成 slave 后会把网络故障那段时间写入自己中的数据清掉,这样数据就丢失了。
解决:
master 在被写入数据时会持续连接 slave mater 确保有 2 slave 可以写入我才允许写入
如果 slave 数量少于 2 个便拒绝写入

七、Redis Cluster(无中心化设计)

1:Redis Cluster 工作原理

在哨兵 sentinel 机制中,可以解决 redis 高可用问题,即当 master 故障后可以自动将 slave 提升为 master , 从而可以保证redis 服务的正常使用,但是无法解决 redis 单机写入的瓶颈问题,即单机 redis 写入性能受限于单机的内存大小、并发数量、网卡速率等因素。
redis 3.0 版本之后推出了无中心架构的 redis cluster 机制,在无中心的 redis 集群当中,其每个节点保存当前节点数据和整个集群状态, 每个节点都和其他所有节点连接
Redis Cluster特点如下
  • 所有Redis节点使用(PING机制)互联
  • 集群中某个节点的是否失效,是由整个集群中超过半数的节点监测都失效,才能算真正的失效
  • 客户端不需要proxy即可直接连接redis,应用程序中需要配置有全部的redis服务器IP redis cluster把所有的redis node 平均映射到 0-16383个槽位(slot)上,读写需要到指定的redis node上进行操作,因此有多少个redis node相当于redis 并发扩展了多少倍,每个redis node 承担 16384/N个槽位
  • Redis cluster预先分配16384(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。
Redis cluster 架构

假如三个主节点分别是: A, B, C 三个节点,采用哈希槽 (hash slot) 的方式来分配 16384 slot 的话它们 三个节点分别承担的slot 区间可以是:
节点 A 覆盖 0 5460
节点 B 覆盖 5461 10922
节点 C 覆盖 10923 16383

Redis cluster 主从架构
Redis cluster 的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个 Redis master 的高可用
如何解决?
那就是对每个 master 节点都实现主从复制 , 从而实现 redis 高可用性
Redis Cluster 部署架构说明

2:创建redis cluster的前提

  • 每个redis node节点采用相同的硬件配置、相同的密码、相同的redis版本。
  • 每个节点必须开启的参数

          cluster-enabled yes

          #必须开启集群状态,开启后redis进程会有cluster显示

         cluster-config-file nodes-6380.conf

         #此文件有redis cluster集群自动创建和维护,不需要任何手 动操作

  • 所有redis服务器必须没有任何数据
  • 先启动为单机redis且没有任何key value

3:部署redis cluster

在所有 redis 主机中

4:redis-cli --cluster 参数说明

5:创建redis-cluster

检测redis集群状态

写入数据

6:集群扩容

# 添加 salve

7: clsuter集群维护

添加节点的时候是先添加 node 节点到集群,然后分配槽位,删除节点的操作与添加节点的操作正好相反,是先将被删除的Redis node 上的槽位迁移到集群中的其他 Redis node 节点上,然后再将其删除,如果一个Redis node 节点上的槽位没有被完全迁移,删除该 node 的时候会提示有数据且无法删除。

实验部分

1、redis部署

[root@redis-node1 redis-7.4.0]# dnf install make gcc initscripts-10.11.6-1.el9.x86_64 -y

[root@redis-node1 redis-7.4.0]# make

[root@redis-node1 redis-7.4.0]# make install

[root@redis-node1 utils]# vim install_server.sh

[root@redis-node1 utils]# vim /etc/redis/6379.conf

[root@redis-node2 ~]# dnf install make gcc initscripts-10.11.6-1.el9.x86_64 -y

[root@redis-node3~]# dnf install make gcc initscripts-10.11.6-1.el9.x86_64 -y

[root@redis-node1 ~]# scp -r redis-7.4.0 root@172.25.254.200:/root

[root@redis-node1 ~]# scp -r redis-7.4.0 root@172.25.254.250:/root

[root@redis-node1 bin]# cd /usr/local/bin

[root@redis-node1 bin]# rsync -al * root@172.25.254.250:/usr/local/bin

root@172.25.254.250's password:

[root@redis-node1 bin]# rsync -al * root@172.25.254.200:/usr/local/bin

root@172.25.254.200's password:

[root@redis-node2-3 utils]# vim /etc/redis/6379.conf

2、主从复制

[root@redis-node1 & node2 & node3 ~]# vim /etc/redis/6379.conf

[root@redis-node1 &node2 & node3 ~]# /etc/init.d/redis_6379 restart

[root@redis-node2 & 3 ~]# vim /etc/redis/6379.conf

[root@redis-node2 & 3 ~]# /etc/init.d/redis_6379 restart

3、哨兵

[root@redis-node1 redis-7.4.0]# cp sentinel.conf /etc/redis/

[root@redis-node1 redis-7.4.0]# vim /etc/redis/sentinel.conf

[root@redis-node1 redis-7.4.0]# scp /etc/redis/sentinel.conf root@172.25.254.200:/etc/redis/sentinel.conf

root@172.25.254.200's password: sentinel.conf 100% 14KB 11.7MB/s 00:00

[root@redis-node1 redis-7.4.0]# scp /etc/redis/sentinel.conf root@172.25.254.250:/etc/redis/sentinel.conf

root@172.25.254.250's password: sentinel.conf 100% 14KB 19.0MB/s 00:00

[root@redis-node1 redis-7.4.0]# cd /etc/redis/

[root@redis-node1 redis]# ls 6379.conf sentinel.conf

[root@redis-node1 redis]# cp sentinel.conf sentinel.conf.bak

[root@redis-node2 utils]# cd /etc/redis/

[root@redis-node2 redis]# ls 6379.conf sentinel.conf

[root@redis-node2 redis]# cp sentinel.conf sentinel.conf.bak

[root@redis-node3 utils]# cd /etc/redis/

[root@redis-node3 redis]# ls 6379.conf sentinel.conf

[root@redis-node3 redis]# cp sentinel.conf sentinel.conf.bak

暂停node1

[root@redis-node1 redis]# ls 6379.conf sentinel.conf sentinel.conf.bak

[root@redis-node1 redis]# vim sentinel.conf

[root@redis-node1 redis]# cp sentinel.conf.bak sentinel.conf

cp:是否覆盖'sentinel.conf'? y

后台运行

[root@redis-node1 redis-7.4.0]# vim /etc/redis/sentinel.conf

4、redis-cluster

[root@redis-node1 redis]# cd

[root@redis-node1 ~]# cd redis-7.4.0/

[root@redis-node1-3 redis-7.4.0]# make uninstall

[root@redis-node1-3 redis-7.4.0]# yum install redis -y

[root@redis-node110-130 redis-7.4.0]# yum install redis -y

[root@redis-node1 ~]# vim /etc/redis/redis.conf

[root@redis-node1 ~]# systemctl enable --now redis.service

Created symlink /etc/systemd/system/multi-user.target.wants/redis.service →/usr/lib/systemd/system/redis.service.

[root@redis-node1 ~]#systemctl restart redis.service

[root@redis-node2-3、110-130 ~]# systemctl enable --now redis.service

创建redis-cluster

检测redis集群状态

写入数据   # 被分配到 200 hash 槽位上

[root@node40 ~]# dnf install redis -y

[root@redis-node140 ~]# dnf install redis -y
[root@redis-node2 ~]# scp /etc/redis/redis.conf  root@172.25.254.40:/etc/redis/redis.conf
root@172.25.254.40's password:
redis.conf                                                                           100%   92KB  31.0MB/s   00:00
[root@redis-node2 ~]# scp /etc/redis/redis.conf  root@172.25.254.140:/etc/redis/redis.conf
root@172.25.254.140's password:
redis.conf                                                                           100%   92KB  23.1MB/s   00:00
[root@redis-node140 ~]# systemctl enable --now redis.service
Created symlink /etc/systemd/system/multi-user.target.wants/redis.service → /usr/lib/systemd/system/redis.service.
[root@redis-node40 ~]# systemctl enable --now redis.service
Created symlink /etc/systemd/system/multi-user.target.wants/redis.service → /usr/lib/systemd/system/redis.service.

集群扩容

 查看信息 

 没有槽位不能存数据

已经出现槽位#添加salve

删除slave

分配槽位

删除40

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

보고.싶다

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值