redis

redis简介

为了提高网站响应速度,企业会将热点数据保存在内存中而不是直接从后端数据库中读取。大型网站应用,热点数据往往巨大,几十G上百G是很正常的事,这种情况下,就需要用到缓存服务器,通过缓存服务器承载大部分用户请求,小部分用户请求交给后端服务器处理,如此一来,就可以大大提高用户访问的速度,提升用户使用体验。

常用的缓存服务器有:

memcache

redis

Redis 是一种开源(BSD 许可)内存中数据结构存储,用作数据库、缓存、消息代理和流引擎。

为了实现最佳性能,Redis 使用 内存数据集。根据您的使用案例,Redis 可以通过定期将数据集转储到磁盘或将每个命令附加到基于磁盘的日志来持久保存您的数据。如果您只需要功能丰富的网络内存缓存,您还可以禁用持久性。

Redis 支持异步复制,具有快速非阻塞同步和自动重新连接以及网络分割上的部分重新同步。

redis集群

redis集群分类

集群是一组相互独立、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群就像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。

redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。

redis集群有三种集群模式:

1.主从模式

2.哨兵(Sentinel)模式

3.Cluster模式

在服务开发中,单机都会存在单点故障的问题,即服务部署在一台服务器上,一旦服务器宕机服务就不可用,所以为了让服务高可用,分布式服务就出现了,将同一服务部署到多台机器上,即使其中几台服务器宕机,只要有一台服务器可用服务就可用。

redis也是一样,为了解决单机故障引入了主从模式,但主从模式存在一个问题:master节点故障后服务,需要人为的手动将slave节点切换成为maser节点后服务才恢复。redis为解决这一问题又引入了哨兵模式,哨兵模式能在master节点故障后能自动将salve节点提升成master节点,不需要人工干预操作就能恢复服务可用。

但是主从模式、哨兵模式都没有达到真正的数据sharding(分布式)存储,每个redis实例中存储的都是全量数据,所以redis cluster就诞生了,实现了真正的数据分片存储。

主从模式

redis单节点虽然有通过RDB和AOF持久化机制能将数据持久化到硬盘上,但数据是存储在一台服务器上的,如果服务器出现硬盘故障等问题,会导致数据不可用,而且读写无法分离,读写都在同一台服务器上,请求量大时会出现I/O瓶颈。

为了避免单点故障 和 读写不分离,Redis 提供了复制(replication)功能实现master数据库中的数据更新后,会自动将更新的数据同步到其他slave数据库上。

通过数据复制,Redis 的一个 master 可以挂载多个 slave,而 slave 下还可以挂载多个 slave,形成多层嵌套结构。所有写操作都在 master 实例中进行,master 执行完毕后,将写指令分发给挂在自己下面的 slave 节点。slave 节点下如果有嵌套的 slave,会将收到的写指令进一步分发给挂在自己下面的 slave。

通过多个 slave,Redis 的节点数据就可以实现多副本保存,任何一个节点异常都不会导致数据丢失,同时多 slave 可以 N 倍提升读性能。master 只写不读,这样整个 master-slave 组合,读写能力都可以得到大幅提升。

主从模式优缺点:

1、优点: 主从结构具有读写分离,提高效率、数据备份,提供多个副本等优点。

2、不足: 最大的不足就是主从模式不具备自动容错和恢复功能,主节点故障,集群则无法进行工作,可用性比较低,从节点升主节点需要人工手动干预。

普通的主从模式,当主数据库崩溃时,需要手动切换从数据库成为主数据库:

在从数据库中使用SLAVE NO ONE命令将从数据库提升成主数据继续服务。

启动之前崩溃的主数据库,然后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可同步数据。

哨兵模式

主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。

哨兵模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来。

哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个sentinel(哨兵)进程。

哨兵本身也有单点故障的问题,所以在一个一主多从的Redis系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。

哨兵模式的作用

监控所有服务器是否正常运行:通过发送命令返回监控服务器的运行状态,除了监控主服务器、从服务器外,哨兵之间也相互监控。

故障切换:当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。

哨兵模式优缺点

优点:

1、哨兵模式是基于主从模式的,解决主从模式中master故障不能自动切换故障的问题。

缺点:

1、哨兵模式下每台 Redis 服务器都存储相同的数据,很浪费内存空间;数据量太大,主从同步时严重影响了master性能。

2、哨兵模式是中心化的集群实现方案,每个从机和主机的耦合度很高,master宕机到salve选举master恢复期间服务不可用。因为投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机。

3、哨兵模式始终只有一个Redis主机来接收和处理写请求,写操作还是受单机瓶颈影响,没有实现真正的分布式架构。

Cluster模式

主从模式或哨兵模式每个节点存储的数据都是全量的数据,数据量过大时,就需要对存储的数据进行分片后存储到多个redis实例上。此时就要用到Redis Sharding技术。

redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。

Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。

官方推荐 ,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。Redis Cluster集群具有如下几个特点:

1、集群完全去中心化,采用多主多从;所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。

2、客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

3、每一个分区都是由一个Redis主机和多个从机组成,分片和分片之间是相互平行的。

4、每一个master节点负责维护一部分槽,以及槽所映射的键值数据;集群中每个节点都有全量的槽信息,通过槽每个node都知道具体数据存储到哪个node上。

redis cluster主要是针对海量数据+高并发+高可用的场景,如果你的数据量很大,那么建议就用redis cluster,数据量不是很大时,使用sentinel就够了。redis cluster的性能和高可用性均优于哨兵模式。

Redis Cluster采用虚拟哈希槽分区而非一致性hash算法,预先分配一些卡槽,所有的键根据哈希函数映射到这些槽内,每一个分区内的master节点负责维护一部分槽以及槽所映射的键值数据。

redis单机部署

下载需要的软件包,wget make gcc gcc-c++
wget https://download.redis.io/redis-stable.tar.gz

下载需要的包

解压

tar -xzvf redis-stable.tar.gz redis-stable

进入到redis-stable,进行编译安装

[root@node1 ~]# cd redis-stable/
[root@node1 redis-stable]# make
                    // 安装过程省略///
[root@node1 redis-stable]# make install

安装完成后进行配置内核参数

Linux操作系统对大部分申请内存的请求都回复yes, 以便能运行更多的程序。 因为申请内存后, 并不会马上使用内存, 这种技术叫做overcommit。

0:表示内核将检查是否有足够的可用内存。如果有足够的可用内存,内存申请通过,否则内存申请失败,并将错误返回给应用程序。

1:表示内核允许超量使用内存直到用完为止

2:表示内核决不过量使用内存,即系统整个内存地址空间不能超过swap+50%的RAM(运行内存)值,50%是overcommit_ratio的默认值,此参数同样支持修改。

Redis建议把这个值设置为1, 是为了让fork操作能够在低内存下也执行成功。

[root@node1 redis-stable]# echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
[root@node1 redis-stable]# sysctl -p
vm.overcommit_memory = 1
[root@node1 redis-stable]# 

THP透明大页面,尽管THP的本意是为提升性能,但某些数据库厂商还是建议直接关闭THP。否则可能导致性能下降,内存锁,甚至系统重启等问题。

[root@node1 ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled

新建一个目录,里面放redis配置文件

[root@node1 ~]# mkdir /etc/redis
[root@node1 ~]# cd redis-stable/
[root@node1 redis-stable]# ls
00-RELEASENOTES     deps         MANIFESTO               runtest            SECURITY.md    TLS.md
BUGS                INSTALL      README.md               runtest-cluster    sentinel.conf  utils
CODE_OF_CONDUCT.md  LICENSE.txt  redis.conf              runtest-moduleapi  src
CONTRIBUTING.md     Makefile     REDISCONTRIBUTIONS.txt  runtest-sentinel   tests
[root@node1 redis-stable]# cp redis.conf /etc/redis/

使redis在后台运行需要修改配置文件/etc/redis/redis.conf,将daemonize值设为yes

默认情况下,redis连接是不需要经过认证的,而redis承载了企业大部分的请求流量,如果不经过认证很有可能在互联网上遭受攻击,所以需要在配置文件中为redis设置密码认证,且密码最好随机生成,保证没有规律可言。

vim /etc/redis/redis.conf
// 修改daemonize yes为yes,使它在后台运行
// requirepass foobared    //设置密码认证

启动redis

[root@node1 ~]# redis-server /etc/redis/redis.conf    //启动
[root@node1 ~]# ps -ef | grep redis                    // 查看端口
root      133339       1  0 10:30 ?        00:00:00 redis-server 127.0.0.1:6379
root      134971     676  0 10:30 pts/0    00:00:00 grep --color=auto redis
[root@node1 ~]# redis-cli                         // 登录
127.0.0.1:6379> auth foobared
OK

redis主从

[root@node1 redis]# mv redis.conf 6379.conf
[root@node1 redis]# cp 6379.conf 6380.conf
                // 需要多台主机,所以复制配置文件

先修改主的配置文件,6379

vim 6379.conf
添加 masterauth foobared

修改从的配置文件,6380

vim 6380.conf
添加 masterauth foobared
port 6380 // 修改端口为6280
replicaof 127.0.0.1 6379

杀掉之前redis的进程

[root@node1 redis]# ps -ef | grep redis
root      133339       1  0 10:30 ?        00:00:02 redis-server 127.0.0.1:6379
root      168712     676  0 10:44 pts/0    00:00:00 grep --color=auto redis
[root@node1 redis]# pkill redis
[root@node1 redis]# ps -ef | grep redis
root      169414     676  0 10:44 pts/0    00:00:00 grep --color=auto redis

启动主和从

[root@node1 redis]# redis-server /etc/redis/6379.conf
[root@node1 redis]# redis-server /etc/redis/6380.conf
[root@node1 redis]# ps -ef | grep redis
root      177641       1  0 10:48 ?        00:00:00 redis-server 127.0.0.1:6379
root      178348       1  0 10:48 ?        00:00:00 redis-server 127.0.0.1:6380

两台主机已经启动起来了

redis哨兵

讲哨兵的配置文件复制到/etc/redis下

[root@node1 redis-stable]# ls
00-RELEASENOTES     deps         MANIFESTO               runtest            SECURITY.md    TLS.md
BUGS                INSTALL      README.md               runtest-cluster    sentinel.conf  utils
CODE_OF_CONDUCT.md  LICENSE.txt  redis.conf              runtest-moduleapi  src
CONTRIBUTING.md     Makefile     REDISCONTRIBUTIONS.txt  runtest-sentinel   tests
[root@node1 redis-stable]# cp sentinel.conf /etc/redis/
[root@node1 redis-stable]# cd /etc/redis/
[root@node1 redis]# ls
6379.conf  6380.conf  dump.rdb  sentinel.conf

修改哨兵的配置文件

vim /etc/redis/sentinel.conf

protected-mode no  //协议模块设置为no
daemonize yes            // 后台运行
sentinel monitor mymaster 127.0.0.1 6379 1        // 哨兵监控
sentinel auth-pass mymaster foobared                // 设置密码

启动哨兵

[root@node1 redis]# redis-sentinel /etc/redis/sentinel.conf
[root@node1 redis]# ps -ef | grep redis
root      177641       1  0 10:48 ?        00:00:05 redis-server 127.0.0.1:6379
root      178348       1  0 10:48 ?        00:00:05 redis-server 127.0.0.1:6380
root      279840       1  0 11:30 ?        00:00:00 redis-sentinel *:26379 [sentinel]
root      280172     676  0 11:30 pts/0    00:00:00 grep --color=auto redis

在sentinel集群环境下需要多个sentinel互相沟通来确认某个master是否真的死了,quorum这个参数是进行客观下线的一个依据,意思是至少有quorum个sentinel认为这个master有故障,才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以,这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。

相关推荐
做梦敲代码7 分钟前
达梦数据库-读写分离集群部署
数据库·达梦数据库
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger1 小时前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud1 小时前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡1 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷1 小时前
Redis
数据库·redis·缓存
别这么骄傲2 小时前
lookup join 使用缓存参数和不使用缓存参数的执行前后对比
缓存
仰望大佬0072 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
学不透java不改名2 小时前
sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
数据库