redis搭建

一、单机版

1、下载redis
下载地址在:redis.io
比如把Redis安装到/usr/local/soft

cd /usr/local/soft/
wget http://download.redis.io/releases/redis-5.0.5.tar.gz

 2、解压压缩包

tar -zxvf redis-5.0.5.tar.gz

3、安装gcc依赖

Redis是C语言编写的,编译需要

yum install gcc

 4、编译安装

cd redis-5.0.5/src
make MALLOC=libc
make install

安装成功的结果是src目录下面出现服务端和客户端的脚本
redis-server
redis-cli
redis-sentinel

5、修改配置文件
默认的配置文件是/usr/local/soft/redis-5.0.5/redis.conf
后台启动

daemonize no

改成

daemonize yes

下面一行必须改成 bind 0.0.0.0 或注释,否则只能在本机访问

bind 127.0.0.1 

如果需要密码访问,取消requirepass的注释

requirepass yourpassword

 关闭集群(也可以不改,不影响启动,不改成no 启动报警告)

cluster-enbaked no

6、使用指定配置文件启动Redis(这个命令建议配置alias)

/usr/local/soft/redis-5.0.5/src/redis-server /usr/local/soft/redis-5.0.5/redis.conf

7、进入客户端(这个命令建议配置alias)

/usr/local/soft/redis-5.0.5/src/redis-cli

8、停止redis(在客户端中)

redis> shutdown

ps -aux | grep redis
kill -9 xxxx

二、集群版

 1、主从复制

准备三个虚拟机并安装redis-server。按照单机版步骤安装就可以。

例如有三台192.168.152.20 ,192.168.152.30, 192.168.152.40

①在30和40的配置文件中最后添加

slaveof  192.168.152.20 6379 

②在30和40的 cli中。输入命令 slaveof  192.168.152.20 6379 

③./redis-server --slaveof  192.168.152.20 6379  启动参数。 

可以再cli中输入 info replication  查看信息

主从复制的原理:

1.主从之间会建立连接,互相保存ip,端口等信息

①假如slave第一次和master建立连接,会发送数据同步指令,这时是全量复制,每次都会发送的有两个参数指令master_repID,offset,redis的定时serverCron定时发送。

master_repID:在cli中 输入info replication 中可以查看 每一个实例的唯一标示

offecr:偏移量,保证数据一致

步骤说明:

1)一个从数据库在启动后,会向主数据库发送SYNC命令。

2)主数据库在接收到SYNC命令后会开始在后台保存快照(即RDB持久化的过程),并将保存快照期间接收到的命令缓存起来。在该持久化过程中会生成一个.rbd快照文件。

3)在主数据库快照执行完成后,Redis会将快照文件和所有缓存的命令以.rdb快照文件的形式发送给从数据库。

4)从数据库收到主数据库的.rdb快照文件后,载入该快照文件到本地。

5)从数据库执行载入后的.rdb快照文件,将数据写入内存中。

【以上步骤称为复制初始化,以下就是增量复制】

6)在复制初始化结束后,主数据库在每次收到写命令时都会将命令同步给从数据库,从而保证主从数据库的数据一致。

主从模式是实现哨兵和集群的基础。

2、哨兵模式(Sentinel)

https://gper.club/articles/7e7e7f7ff7g5egc7g6a

优点

  • 可以在m挂掉后重新选举产生新的master

2.1环境单机操作

开启哨兵模式,至少需要3个Sentinel实例(奇数个,否则无法选举Leader)。
本例通过3个Sentinel实例监控3个Redis服务(1主2从)。

IP地址	          节点角色&端口
192.168.8.203	Master:6379 / Sentinel : 26379
192.168.8.204	Slave :6379 / Sentinel : 26379
192.168.8.205	Slave :6379 / Sentinel : 26379

防火墙记得关闭!!!

在204和205的redis.conf配置中添加一行

slaveof 192.168.8.203 6379

在203、204、205创建sentinel配置文件(单例安装后根目录下默认有sentinel.conf,可以先备份默认的配置)

cd /usr/local/soft/redis-5.0.5
mkdir logs
mkdir rdbs
mkdir sentinel-tmp
cp sentinel.conf sentinel.conf.bak
>sentinel.conf
vim sentinel.conf

sentinel.conf配置文件内容,三台机器相同

daemonize yes       #后台启动
port 26379          #sentinel端口
protected-mode no   #保护模式
dir "/usr/local/soft/redis-5.0.5/sentinel-tmp"
#sentinel monito <master的名字可以自定义> <ip> <post> <quorum,在故障转移的时候用> 
sentinel monitor redis-master 192.168.8.203 6379 2    
#可以有多个表示监控多个集群
#sentinel monitor redis-master1 192.168.8.xxx 6379 2 
sentinel down-after-milliseconds redis-master 30000  #30s联系不到就认为关闭了
sentinel failover-timeout redis-master 180000
sentinel parallel-syncs redis-master 1

在3台机器上分别启动Redis和Sentinel

cd /usr/local/soft/redis-5.0.5/src
./redis-server ../redis.conf
./redis-sentinel ../sentinel.conf

哨兵节点的另一种启动方式:

./redis-server ../sentinel.conf --sentinel

连接sentinel服务

./redis-cil -p 26379

查看master信息

127.0.0.1:26379>sentinel master redis-master #redis-master自定义的名字

127.0.0.1:26379>sentinel get-master-addr-by-name redis-master #哨兵监控的集群的主节点

在项目中的properties配置文件中之前我们用的是

spring.redis.prot=6379
spring.redis.host=192.168.8.129

使用哨兵之后修改

#三个哨兵
spring.redis.sentinnel.nodes=xxx.xxx.xxxx.xxx:26379,xxxx:26379,xxxx:26379
#监控的集群名字
spring.redis.sentinnel.master=redis-master

至此以及完成了哨兵的故障转移。

2.2原理分析

发现故障,判断依据定时ping。

定时监控

  • 每1s,每个sen会向s、m、sen发送ping做一次心跳检测,来测试是否可达,实现对每个节点的监控;
  • 每2s,每个sen会与其他sen通信,可以发现新sen节点,并与其他sen交换对m的判断信息,方便故障转移和选举
  • 每10s,每个sen会向s、m发送info命令获取最近的拓扑结构,可以感知新加入或故障转移的redis数据节点。

主观下线(sdown)

当sen节点ping其他节点,超时,sen就会对该节点做失败判定。

主观下线是当前sen的一家之言,存在误判。

客观下线(Odown)

当sen主观下线的节点为m,sen会向其他sen询问对该m的判断,当“大多数”sen都对m的下线做了同意判断,那这个判断就是客观的。“大多数”的值就是由在conf中的这个参数的最后一个参数2控制

sentinel monitor redis-master 192.168.8.203 6379 2   

Sentinel领导者选举

sen对m做了客观下线,但还不能立刻进行故障转移,因此故障转移只需要一个sen来完成,因此在sen集群中要选出一个leader进行故障转移

redis使用了raft算法来实现领导者选举

  • 每个在线的sen都有资格成为领导者,它要求其他节点来投自己一票
  • 先收到谁的要求就给谁投票,但不能给自己投
  • 先拿到大多数票的当选领导者,大多数就是conf中sentinel monitor最后一个参数

选择哪个slave成为master?

sen领导者负责此次故障转移:

  1. 排除主观下线的s;
  2. 选择优先级高的s,如果没有再进行3;优先级可以配置
  3. 选择复制偏移量最大的s(复制的最完整),如果没有再进行4;
  4. 选择runid最小的s。

根据上面四个条件选出一个s成为master。

选举会出现脑裂问题, 出现两个master,网络恢复后会丢失一个m的数据。

官网描述脑裂问题,不能避免可以预防

https://redis.io/docs/management/sentinel/

 使用参数预防

min-replicas-to-write 1  #必须有多少个从节点 才可以写数据 否则不能写数据
min-replicas-max-lag 10  #小于等于10s 告诉我结果 

3、集群3主3从

redis可以做到高可用(故障自动转移)的同时实现负载,集群就是解决负载问题,不同的key到不同的机器。

为了节省机器,我们直接把6个Redis实例安装在同一台机器上(3主3从),只是使用不同的端口号。
机器IP 192.168.8.207

更新:新版的cluster已经不需要通过ruby脚本创建,删掉了ruby相关依赖的安装

cd /usr/local/soft/redis-5.0.5
mkdir redis-cluster
cd redis-cluster
mkdir 7291 7292 7293 7294 7295 7296

复制redis配置文件到7291目录

cp /usr/local/soft/redis-5.0.5/redis.conf /usr/local/soft/redis-5.0.5/redis-cluster/7291

修改7291的redis.conf配置文件,内容:

cd /usr/local/soft/redis-5.0.5/redis-cluster/7291
vim redis-conf

修改内容

port 7291              #修改端口
daemonize yes          #后台启动
protected-mode no      #保护模式
bind xxx.xxx.xx.xxx    #必须绑定当前机器的ip,方便redis集群定位机器
dir /usr/local/soft/redis-5.0.5/redis-cluster/7291/   #配置文件路径 日志会在这个路径下
cluster-enabled yes                    #启动集群模式
cluster-config-file nodes-7291.conf    #和端口对应上
cluster-node-timeout 5000
appendonly yes                         #开启日志

注意,外网集群要添加这个配置:

# 实际给各节点网卡分配的IP(公网IP)
cluster-announce-ip 47.xx.xx.xx
# 节点映射端口
cluster-announce-port ${PORT}
# 节点总线端口
cluster-announce-bus-port 1${PORT}

把7291下的redis.conf复制到其他5个目录。

cd /usr/local/soft/redis-5.0.5/redis-cluster/7291
cp redis.conf ../7292
cp redis.conf ../7293
cp redis.conf ../7294
cp redis.conf ../7295
cp redis.conf ../7296

批量替换内容

cd /usr/local/soft/redis-5.0.5/redis-cluster
sed -i 's/7291/7292/g' 7292/redis.conf
sed -i 's/7291/7293/g' 7293/redis.conf
sed -i 's/7291/7294/g' 7294/redis.conf
sed -i 's/7291/7295/g' 7295/redis.conf
sed -i 's/7291/7296/g' 7296/redis.conf

也可以进入文件使用

:%s/源内容/替换内容/g
:%s/7291/7292/g   #将全文的7291替换为7292

启动6个Redis节点

cd /usr/local/soft/redis-5.0.5/
./src/redis-server redis-cluster/7291/redis.conf
./src/redis-server redis-cluster/7292/redis.conf
./src/redis-server redis-cluster/7293/redis.conf
./src/redis-server redis-cluster/7294/redis.conf
./src/redis-server redis-cluster/7295/redis.conf
./src/redis-server redis-cluster/7296/redis.conf

是否启动了6个进程

ps -ef|grep redis

我们发现集群的后面有【cluster】。

关键 重要   创建集群
旧版本中的redis-trib.rb已经废弃了,直接用–cluster命令
注意用绝对IP,不要用127.0.0.1

cd /usr/local/soft/redis-5.0.5/src/
redis-cli --cluster create 192.168.8.207:7291 192.168.8.207:7292 192.168.8.207:7293 192.168.8.207:7294 192.168.8.207:7295 192.168.8.207:7296 --cluster-replicas 1

Redis会给出一个预计的方案,对6个节点分配3主3从,如果认为没有问题,输入yes确认

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:7295 to 127.0.0.1:7291
Adding replica 127.0.0.1:7296 to 127.0.0.1:7292
Adding replica 127.0.0.1:7294 to 127.0.0.1:7293
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: dfdc9c0589219f727e4fd0ad8dafaf7e0cfb4f1c 127.0.0.1:7291
   slots:[0-5460] (5461 slots) master
M: 8c878b45905bba3d7366c89ec51bd0cd7ce959f8 127.0.0.1:7292
   slots:[5461-10922] (5462 slots) master
M: aeeb7d7076d9b25a7805ac6f508497b43887e599 127.0.0.1:7293
   slots:[10923-16383] (5461 slots) master
S: ebc479e609ff8f6ca9283947530919c559a08f80 127.0.0.1:7294
   replicates aeeb7d7076d9b25a7805ac6f508497b43887e599
S: 49385ed6e58469ef900ec48e5912e5f7b7505f6e 127.0.0.1:7295
   replicates dfdc9c0589219f727e4fd0ad8dafaf7e0cfb4f1c
S: 8d6227aefc4830065624ff6c1dd795d2d5ad094a 127.0.0.1:7296
   replicates 8c878b45905bba3d7366c89ec51bd0cd7ce959f8
Can I set the above configuration? (type 'yes' to accept): 

注意看slot的分布:

7291  [0-5460] (5461个槽) 
7292  [5461-10922] (5462个槽) 
7293  [10923-16383] (5461个槽)

集群创建完成

>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 127.0.0.1:7291)
M: dfdc9c0589219f727e4fd0ad8dafaf7e0cfb4f1c 127.0.0.1:7291
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 8c878b45905bba3d7366c89ec51bd0cd7ce959f8 127.0.0.1:7292
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: aeeb7d7076d9b25a7805ac6f508497b43887e599 127.0.0.1:7293
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 8d6227aefc4830065624ff6c1dd795d2d5ad094a 127.0.0.1:7296
   slots: (0 slots) slave
   replicates aeeb7d7076d9b25a7805ac6f508497b43887e599
S: ebc479e609ff8f6ca9283947530919c559a08f80 127.0.0.1:7294
   slots: (0 slots) slave
   replicates dfdc9c0589219f727e4fd0ad8dafaf7e0cfb4f1c
S: 49385ed6e58469ef900ec48e5912e5f7b7505f6e 127.0.0.1:7295
   slots: (0 slots) slave
   replicates 8c878b45905bba3d7366c89ec51bd0cd7ce959f8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

重置集群的方式是在每个节点上个执行cluster reset,然后重新创建集群

连接到客户端

./redis-cli -c -h xxx.xx.xxx.xxx -p 63xx  #-c 集群 -h host地址 -p port端口

我在 6377上存储值,可以看到数据存储到了6378上了

[root@hadoop100 redis-7.2.4]# /usr/local/redis-7.2.4/src/redis-cli -c -h 192.168.194.100 -p 6377
192.168.194.100:6377> set key6377 6377
-> Redirected to slot [7397] located at 192.168.194.100:6378
OK
192.168.194.100:6378> set key6378 6378
-> Redirected to slot [11530] located at 192.168.194.100:6380
OK
192.168.194.100:6380>

 在6383上取值

[root@hadoop100 redis-7.2.4]# /usr/local/redis-7.2.4/src/redis-cli -c -h 192.168.194.100 -p 6383
192.168.194.100:6383> get key6378
-> Redirected to slot [11530] located at 192.168.194.100:6380
"6378"
192.168.194.100:6380>
192.168.194.100:6380> cluster info   #打印集群的信息
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:3
cluster_stats_messages_ping_sent:2951
cluster_stats_messages_pong_sent:3197
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:6149
cluster_stats_messages_ping_received:3197
cluster_stats_messages_pong_received:2952
cluster_stats_messages_received:6149
total_cluster_links_buffer_limit_exceeded:0
192.168.194.100:6380> cluster nodes   #列出集群当前已知的所有节点(node),以及这些节点的相关信息
19acbca3328810b0e339496c8e4cc51561e172ed 192.168.194.100:6381@16381 slave 6f80a89f5c44532f99c87050c526418c902dcc2a 0 1708399597000 2 connected
1dacce8b0991566340dc0232dc0e78405a241680 192.168.194.100:6383@16383 slave c25b1cbbd9bd42c93752d078179b5f93c22801cc 0 1708399597033 1 connected
4ec9bbfc8ef5c866c01dde915d60b6aff67f8908 192.168.194.100:6380@16380 myself,master - 0 1708399596000 3 connected 10923-16383
c25b1cbbd9bd42c93752d078179b5f93c22801cc 192.168.194.100:6377@16377 master - 0 1708399596015 1 connected 0-5460
6f80a89f5c44532f99c87050c526418c902dcc2a 192.168.194.100:6378@16378 master - 0 1708399595000 2 connected 5461-10922
9cd8cbfca66e1147e85c404d2dba802a86736bec 192.168.194.100:6382@16382 slave 4ec9bbfc8ef5c866c01dde915d60b6aff67f8908 0 1708399598050 3 connected
192.168.194.100:6380>

附录:

集群命令

cluster info :打印集群的信息
cluster nodes :列出集群当前已知的所有节点(node),以及这些节点的相关信息。
cluster meet :将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster forget <node_id> :从集群中移除 node_id 指定的节点(保证空槽道)。
cluster replicate <node_id> :将当前节点设置为 node_id 指定的节点的从节点。
cluster saveconfig :将节点的配置文件保存到硬盘里面。

槽slot命令

cluster addslots [slot …] :将一个或多个槽(slot)指派(assign)给当前节点。
cluster delslots [slot …] :移除一个或多个槽对当前节点的指派。
cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
cluster setslot node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
cluster setslot migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。
cluster setslot importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。
cluster setslot stable :取消对槽 slot 的导入(import)或者迁移(migrate)。

键命令

cluster keyslot :计算键 key 应该被放置在哪个槽上。
cluster countkeysinslot :返回槽 slot 目前包含的键值对数量。
cluster getkeysinslot :返回 count 个 slot 槽中的键

通过springBoot项目连接。读取

 引入jedis.jar。

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

创建

    public static void main(String[] args) {
        Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
        jedisClusterNode.add(new HostAndPort("192.168.194.100",6378));
        jedisClusterNode.add(new HostAndPort("192.168.194.100",6377));
        jedisClusterNode.add(new HostAndPort("192.168.194.100",6380));
        jedisClusterNode.add(new HostAndPort("192.168.194.100",6381));
        jedisClusterNode.add(new HostAndPort("192.168.194.100",6382));
        jedisClusterNode.add(new HostAndPort("192.168.194.100",6383));
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(10);
        config.setMaxTotal(100);
        JedisCluster jedisCluster = new JedisCluster(jedisClusterNode,6000,10,config);
        System.out.println(jedisCluster.get("key6378"));


    }

 application.properties中配置,这与上面不一样这个引入的是spring-boot-starter-data-redis

#集群
spring.redis.cluster.max-redirects=100
spring.redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6383,127.0.0.1:6384

三、java与redis的整合

1.jedis使用方式

【Redis高手修炼之路】Jedis——Jedis的基本使用-CSDN博客

2.springboot整合redis

redisTemplate的api使用

RedisTemplate操作Redis,这一篇文章就够了(一)-阿里云开发者社区

jedis和redistemplate异同

JedisRedisTemplate都是用于操作Redis数据库的客户端。我们经常使用Redis作为缓存或者数据存储的解决方案,在与Redis进行交与时,主要的库可以使用:RedisTemplate和Jedis,这两个库都可以实。

不同

  1. 依赖关系:

    • Jedis是独立于任何框架的客户端库,需要用户自行处理连接池、异常等问题。
    • RedisTemplate是Spring Data Redis提供的操作模板类,它内置了对Spring框架的支持,可以自动管理连接池。
  2. 性能:

    • Jedis的性能通常较高,因为它是基于原生Socket通信的,而RedisTemplate的性能可能不如Jedis。
    • 在高并发和性能要求高的场景下,Jedis可能是更好的选择,因为它可以提供更高的性能。
  3. 命令支持:

    • Jedis支持Redis的所有命令,并且可以通过JedisPool来控制连接的生命周期。
    • RedisTemplate提供了对Redis常用操作的简化封装,使用起来更加方便,但可能不支持所有Redis命令。
  4. 使用便利性:

    • 使用RedisTemplate时,Spring会自动管理连接池,简化了配置和管理的过程。
    • Jedis则需要用户手动处理连接池和异常问题,这可能增加开发的复杂性。
  5. 框架兼容性:

    • RedisTemplate是对Jedis的封装,并且在Spring Boot 2.0之后,Spring Data Redis默认使用lettuce作为底层通信库。
    • Jedis可以结合jedisPool使用,以确保连接可控,但这种方式需要用户自行管理连接池。

RedisTemplate的主要优点是:

集成了Spring框架,可以与其他Spring组件无缝集成。
提供了一个高级的API,可以直接操作Java对象而不需要手动进行序列化和反序列化。
支持事务管理,可以保证多个操作的原子性。
提供了对Redis各种数据结构的封装方法

Jedis的主要优点是:

简单易用,学习成本低。
对Redis命令的支持更全面,更贴近原生的Redis命令。
性能较高,因为它是一个轻量级的客户端库。

  • 35
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值