复习电商笔记-31-redis哨兵

 

商品类目添加缓存

1)将结果数据保存到redis中,注意key的定义,不要太长,不要相同。将java对象序列化成json字符串,同时可设置生存时间。

2)检测缓存中是否存在,如果存在就返回。不存在就直接去数据库进行查询。(如果有异常,要捕获处理,不能影响正常业务逻辑)

 

 

修改ItemCatService.java文件

package com.jt.manage.service;

import java.io.IOException;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.common.service.RedisService;
import com.jt.manage.mapper.ItemCatMapper;
import com.jt.manage.pojo.ItemCat;

@Service
public class ItemCatService extends BaseService<ItemCat>{
	@Autowired
	private ItemCatMapper itemCatMapper;
	@Autowired
	private RedisService redisService;
	//引入java对象和json串转换对象ObjectMapper;全局唯一
	private static final ObjectMapper MAPPER = new ObjectMapper();
	
	public List<ItemCat> queryByPid(Integer id) throws IOException{
		/*
		 * 商品分类要使用缓存步骤:
		 * 1)先判断缓存中是否有数据,如果有数据就读取,直接返回
		 * 2)如果缓存中没有数据,要继续执行业务,不能抛出异常
		 * 3)执行完业务,要多一步动作,要把结果放入缓存中string,先把java对象转换成json串,kv写入缓存中。
		 */
		
	MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		String ITEM_CAT_KEY = "ITEM_CAT_" + id;	//唯一性
		
		//从redis中获取数据
		String jsonItemCat = redisService.get(ITEM_CAT_KEY);
		if(StringUtils.isNotEmpty(jsonItemCat)){
			JsonNode jsonNode = MAPPER.readTree(jsonItemCat);	//把json串转换JsonNode
			//利用jackson提供方法,将json串转成java对象,List<Object>
			List<ItemCat> itemCatList = MAPPER.readValue(jsonNode.traverse(),
                    MAPPER.getTypeFactory().constructCollectionType(List.class, ItemCat.class));
			return itemCatList;
		}else{
			//继续执行业务,一般都是去数据库访问
			List<ItemCat> itemCatList = itemCatMapper.queryByPid(id);
			
			//写redis,kv(string,string)
			jsonItemCat = MAPPER.writeValueAsString(itemCatList);	//将java对象转成json串
			redisService.set(ITEM_CAT_KEY, jsonItemCat);
			return itemCatList;
		}
	}

}

 

Redis主从复制

 

 

主从复制

cp redis.conf redis-master.conf		#主节点配置
redis-server redis-master.conf		#启动主

cp redis.conf redis-slave01.conf		#从1配置,修改端口 6380
redis-server redis-slave01.conf		#启动从1
redis-cli –p 6380						#登录从1
slaveof 127.0.0.1 6379				#挂接到主

cp redis.conf redis-slave02.conf		#从2配置,修改端口6381
redis-server redis-slave02.conf		#启动从2
redis-cli –p 6381						#登录从2
slaveof 127.0.0.1 6379				#挂接到主

检查配置

info					#查看所有信息
info Replication		#只查看Replication片段信息

查看结果,确认状态

127.0.0.1:6379> info Replication
# Replication
role:master			#说明master生效
connected_slaves:2		#master主节点下有两个从节点
slave0:ip=127.0.0.1,port=6380,state=online,offset=845,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=845,lag=1
master_repl_offset:845
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:844
127.0.0.1:6379>

测试

127.0.0.1:6379>set name tony
127.0.0.1:6380>get name			#读取到同步的信息
127.0.0.1:6381>get name
127.0.0.1:6381>set name hellen	#报错,从上不允许设置数据
(error) READONLY You can't write against a read only slave.

 

Redis哨兵实现HA高可用

哨兵实现实时冗余备份和容灾,但不支持分片。

 

 

哨兵sentinel

Redis Sentinel(哨兵)是一个分布式系统,你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。

Sentinel系统用于管理多个Redis服务器(instance),该系统执行以下三个任务:

  1. 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  2. 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时,Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  3. 自动故障迁移(Automatic failover):当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

 

 

哨兵的工作原理

 sentinel以每10秒一次的频率向master发送info命令,通过info的回复来分析master信息,master的回复主要包含了两部分信息,一部分是master自身的信息,一部分是master所有的slave(从)的信息,所以sentinel可以自动发现master的从服务。sentinel从master获取到的master自身信息以及master所有的从信息,将会更新到sentinel的sentinelState中及masters(sentinelRedisInstance结构)中的slaves字典中。

 

 

哨兵sentinel-实现高可用

哨兵sentinel类似zookeeper。它含有监控,监控每个节点的活跃状态。

上面配置了3个节点,但如果主宕机,整个缓存系统就瘫痪,如何实现主宕机,自动从多个从中选举出一个节点当主呢?redis在3.0版本之后提供了哨兵sentinel。通过哨兵实现高可用。

但一个哨兵也可能宕机,一次启动两个哨兵,自身也实现高可用。

cp sentinel.conf sentinel2.conf			#复制哨兵
26379为26380								#修改端口
sentinel monitor mymaster 192.168.163.20 6379 1		#设置访问名称
											#最后的数值为选举时过票数量(坑)
redis-sentinel sentinel.conf				#启动哨兵
redis-sentinel sentinel2.conf				#启动哨兵2,形成哨兵的高可用

ps –ef|grep redis    #查看进程

6010  5709  0 00:38 pts/2    00:00:13 redis-server 127.0.0.1:6379

6012  5710  0 00:38 pts/2    00:00:13 redis-server 127.0.0.1:6380

6014  5721  0 00:38 pts/3    00:00:13 redis-server 127.0.0.1:6381

6018  5927  1 00:39 pts/6    00:00:21 redis-server *:26379 [sentinel]     

6047  6037  1 00:41 pts/7    00:00:19 redis-server *:26380 [sentinel]      

6241  2512  0 01:10 pts/1    00:00:00 grep redis

测试

kill 6010     #可以看到slave的两个节点开始报链接拒绝错误,不一会哨兵将6380切换为主

info          #在6380上info命令,可以看到其role:master

kill 6018     #删除一个哨兵,在6380上set数据,6381自动同步

 

 

sentinel的坑

 

 

 

 

开放端口或者关闭防火墙

6379,6380,6381

26379,26380

service iptables stop

 

 

 

 

protected-mode

默认情况下,Redis node和sentinel的protected-mode都是yes,在搭建集群时,若想从远程连接redis集群,需要将redis node和sentinel的protected-mode修改为no,若只修改redis node,从远程连接sentinel后,依然是无法正常使用的,且sentinel的配置文件中没有protected-mode配置项,需要手工添加。

 

 

 

 

远程访问拒绝

sentinel.conf默认配置

sentinel monitor mymaster 127.0.0.1 6380 1

当redis和sentinel在一台服务器上时,必须指定实际的IP地址

sentinel monitor mymaster 192.168.163.30 6380 1

 

 

 

选举数

sentinel.conf中96行左右的位置

sentinel monitor mymaster 127.0.0.1 6379 2

最后的2代表选举的个数,这个值非常关键。其中的2表示只有在两个sential进程发现master不可用时才执行failover故障转移。例如:即使一个master宕机,如果投票个数未超过1个,redis不会触发failover,不会触发选举,而是一直等待master恢复,当master恢复,一切又工作正常。只有当投票数大于等于1时,才认为master才会触发选举,自动从众多的slave中选择一个节点升级为master,其他自动从节点自动连接次节点。同时会自动修改sentinel.conf文件

sentinel monitor mymaster 192.168.163.30 6380 1

默认30秒进行切换

 

 

修改从节点的选举优先级

redis.conf

slave-priority 100	

这样当Master挂掉的时候Sentinel会优先选择slave-priority值较小的作为新的Master。

 

 

sentinel.conf配置详解

配置语句

说明

daemonize yes

以后台进程模式运行

port 26379

哨兵的端口号,该端口号默认为26379,不得与任何redis node的端口号重复

logfile " /var/log/redis/sentinel.log "

log文件所在地

sentinel monitor master1 192.168.163.30 6379 1

(第一次配置时)哨兵对哪个master进行监测,此处的master1为一“别名”可以任意,将来程序访问时使用,如sentinel-26379。然后哨兵会通过这个别名后的IP知道整个该master内的slave关系。因此你不用在此配置slave是什么而由哨兵自己去维护这个“链表”。

sentinel monitor master1 192.168.163.30 6379 1

最后一个1代表当节点宕机时的触发选举的判断条件,1就代表sentinel认定宕机的个数,必须大于这个个数,选举才开始发生,默认值为2,很坑。

sentinel down-after-milliseconds master1 1000

如果master在多少秒内无反应哨兵会开始进行master-slave间的切换,使用“选举”机制

sentinel failover-timeout master1 5000

如果在多少秒内没有把宕掉的那台master恢复,那哨兵认为这是一次真正的宕机,而排除该宕掉的master作为节点选取时可用的node然后等待一定的设定值的毫秒数后再来探测该节点是否恢复,如果恢复就把它作为一台slave加入哨兵监测节点群并在下一次切换时为他分配一个“选取号”。

 

 

 

安全访问

redis.conf

masterauth "123456"

requirepass "123456"

sentinel.conf

sentinel auth-pass mymaster 123456

否则在每个的redis-cli中执行语句:

CONFIG SET protected-mode no

jedis访问时

jedis.auth("123456");

 

 

jedis访问sentinel

@Test
	public void sentinel(){
    	Set<String> sentinels = new HashSet<String>();
    	sentinels.add(new HostAndPort("192.168.163.30",26379).toString());
    	//sentinels.add(new HostAndPort("192.168.163.30",26380).toString());
    	
    	//mymaster是在sentinel.conf中配置的名称
    	//sentinel monitor mymaster 192.168.163.30 6380 1
    	JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);
    	System.out.println("当前master:" + pool.getCurrentHostMaster());
    	
    	Jedis jedis = pool.getResource();
		//jedis.auth("123456");

    	System.out.println(jedis.get("num"));
    	pool.returnResource(jedis);   
    	
    	pool.destroy();
    	System.out.println("ok");
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值