redis学习

一、介绍redis

1、定义: nosql的,key-value的,内存的,可持久化的,缓存执行逻辑的,非关系型数据库。
2、读写吞吐量高:单位时间处理的数据量大; 秒级万条数据(万条key-value)
3、优点:快,redis完全基于运行中的内存数据来处理读写功能的.区别mysql存储在磁盘的读写速度.
缺点:断电数据丢失/量少容易造成基于内存的缓存出现雪崩/缓存击穿
4、运行过程中,可以利用持久化能力将内存需要提高可靠性的数据写入到磁盘中.保证宕机后即使内存数据断电丢失也可以从持久化文件中恢复数据

二、数据类型

五种类型:String(键值对) Hash(存个对象) List(先进先出) Set(无序的散点集) Zset(有序散点集)

1、String操作
set key value:存储一个key-value结构的数据;
get key:获取当前key对应的value数据;
exists key:判断当前节点是否包含key的数据(如果不存在返回0,存在返回1);
del key:删除key值对应的key-value数据;
type key:查看当前key的类型;
save:将当前的内存数据保存到磁盘文件;
value的值如果是纯数字,也有一些简单的数字操作命令:incr/decr key:自增1,自减1;计步器

2、Hash操作
hset key field value:设置一个变量的属性和值。 hset user username hanlaoshi
hget key field:返回一个变量的属性值。hget user username
hexists key field:判断hash类型中的属性值是否存在。hexists user age
hmset和hmget:批量设置,不支持分布式。设置:hmset student age 19 name wangxiaoxiao gender male 获取:hmget student age name gender
hdel student age:删除单个属性
hkeys/hvals user:批量获取键/值
Hlen key:获取属性个数(长度)

3、List操作
lpush key value/vlaues:对于一个链表,从左(上)开始插入数据; 。lpush mylist01 100 200 300
lrange key 起始下标 结束下标(展示范围,结束下标是-1表示到尾部): lrange mylist01 0 1 返回0和1位置的数
Rpush key value:从下向上插入数据
linsert mylist01 before 100 one:在mylist01链表中,找到100这个元素,从前插入数据one
lset key index value:将下标对应的数据修改
lpop/rpop key:从list头部删除元素,返回删除结果(类似remove)
rpoplpush key1 key2:从第一个list的尾部删除数据,移动到第二个list的头部添加

4、set操作
sadd key member:添加内容到set,member可以是多个
srem key member:移出set的内容
scard key :返回元素个数
sismember key element:判断元素是否在集合中
srandmember key: 随机抽取几个元素
smembers key:获取所有元素
sinter/suinon/sdiff set1 set2 :交集/并集/后者的差集

5、ZSet操作
zadd key score memeber:添加成员,可以指定分数将来做排名/计算用
zscore key member:返回某个成员的分数
zrank key member:计算某个成员的排名
zrem key member:删除某个成员
zincrby key increment member:增加某个成员的分数
zrange key start end:返回指定排名内的成员
zrangebysore key min max:返回指定分数范围的成员
。。。

三、分布式说明&API

1、hash取余算法
公式: (key.hashCode()&Integer.MAX_VALUE)%N
其中N是分片的个数(3),key是字符串;
但是结果会产生数据偏移并且扩容的时候变化量很大。
在这里插入图片描述

public void test04(){
	//将节点信息包装成一个list对象
	List<JedisShardInfo> info=new ArrayList<JedisShardInfo>();
	info.add(new JedisShardInfo("10.9.100.26", 6379));
	info.add(new JedisShardInfo("10.9.100.26", 6380));
	info.add(new JedisShardInfo("10.9.100.26", 6381));
	ShardedJedis sJedis=new ShardedJedis(info);
	//可以实现分片的hash一致性切分计算
	for(int i=0;i<1000;i++){
		String key=UUID.randomUUID().toString();
		String value="";
		sJedis.set(key, value);
	}
}

2、hash一致性基本算法
以将内存中对象转化成0-2^32-1整数区间(hashCode()区别没符号全是正整数),对象不变,结果也不变.hash一致性数学基础。
通过散列算法得到的hash环上的各种整数结果,决定key值与node的对应关系:顺时针寻找最近节点整数,做对应关系。
在这里插入图片描述

public void test05(){
	//收集节点信息
	List<JedisShardInfo> info=new ArrayList<JedisShardInfo>();
	info.add(new JedisShardInfo("10.9.100.26", 6379, 1000, 1000, 10));
	info.add(new JedisShardInfo("10.9.100.26", 6380, 1000, 1000, 10));
	info.add(new JedisShardInfo("10.9.100.26", 6381, 1000, 1000, 10));
	//构造一个连接池配置属性的配置对象
	//最大连接数,最大空闲
	GenericObjectPoolConfig config=new GenericObjectPoolConfig();
	config.setMaxIdle(8);
	config.setMinIdle(3);
	config.setMaxTotal(200);
	//构造连接池
	ShardedJedisPool pool=new ShardedJedisPool(config, info);
	//从连接池获取连接资源(ShardedJedis)
	ShardedJedis sJedis = pool.getResource();
	sJedis.set("name", "郝老师");
}

四、高可用集群

1、原理
问题分析:不支持高可用,一旦某个节点宕机,节点中的数据就不再支持系统使用,会造成user登录逻辑失效,缓存逻辑数据未命中造成数据库压力过大。要想实现高可用的主从替换功能,需要数据备份做基础。先引入哨兵模式后介绍redis-cluster模式,补充哨兵模式的缺点。

2、多种集群模式
①搭建主从结构
a准备三台redis
复制一下conf文件即可
cp redis.conf 6382redis.conf
cp redis.conf 6383redis.conf
cp redis.conf 6384redis.conf
b修改端口
:%s/6379/6382/g
:%s/6379/6383/g
:%s/6379/6384/g
c启动
默认情况下每个节点启动后都是主节点
redis-server 6382redis.conf
redis-server 6383redis.conf
redis-server 6384redis.conf
d挂载
分别登录从节点的客户端执行挂接命令
127.0.0.1:6383> slaveof 10.9.100.26 6382
127.0.0.1:6384> slaveof 10.9.100.26 6382
②哨兵集群模式
a原理
启动的哨兵进程,自动根据配置监听主从结构中的主节点, 通过info命令获取主从所有节点信息,并且监听主节点状态 (rpc远程传输协议,心跳检测 每秒检测一次),对于主从结构 中需要判断事件(主节点宕机,从节点顶替),发起投票.过半投 票都通过,事件的结果才确定. 例如:5个哨兵进程监听一个主从,3个投票通过过半(最多宕机2个,需要配置主观下线票数)
b修改配置文件
三个哨兵进程监听一个主从结构,修改redis根目录模板文sentinel.conf。
在这里插入图片描述
在这里插入图片描述
c复制三份,修改端口
cp sentinel.conf sentinel01.conf
cp sentinel.conf sentinel02.conf
cp sentinel.conf sentinel03.conf
d分别启动
redis sentinel sentinel01.conf
redis sentinel sentinel02.conf
redis sentinel sentinel03.conf
3、redis-cluster模式
a原理图
在这里插入图片描述
b解释
两两互联,基于二进制传输协议,优化了传输速度(cluster的结构基础)
集群中的哨兵监听逻辑存在,整合到了cluster的master节点中.集群的最小master数量是3个(相当于哨兵主观下线票数过半2),监听所有的节点实现故障转移,宕机替换的投票机制.。
客户端使用的效果变化了,可以通过客户端传递的数据计算分片的逻辑(hash取模的槽道计算).客户端无论连接哪一个节点都可以将数据存储在对应正确的主节点中, 从而从节点同步数据—分片计算逻辑不再使用hash一致性。
hash槽道引入,集群中维护了槽道逻辑–16384个槽道号,每个分片维护一部分槽道号(就是取余计算–hash取模,取余的N是固定的16384),将key值做取模,对应一个槽道号,key值和槽道号强耦合,但是节点(master)管理的槽道号可以调整,将key与node的强耦合通过槽道引入,解耦了 key–>slot–>node
c搭建目标
在这里插入图片描述
客户端可以不关心数据分片计算,在集群中维护了槽道的使用逻辑,一旦数据发送到节点节点运行步骤:
1节点获取key值
2节点通过KEY.CRC16()%16384获取槽道号
3判断槽道号是否在管理范围
4如果在管理范围直接处理数据(读写)
5如果不在管理范围,通知客户端转向正确管理节点的信息重新连接(redirect),重新到1步骤执行

d集群搭建
1方便起见先建立文件夹: mkdir 8000 8001 8002 8003 8004 8005
2将conf文件修改一下名字: cp redis.conf redis-cluster.conf
3修改
593行为appendonly yes 表示配置aof的持久化文件名称
721行为cluster-enabled yes 表示开启cluster节点模式
729行为cluster-config-file nodes-8000.conf 打开集群配置持久化文件nodes
4分发到各文件夹
cp redis-cluster.conf 8000
5修改端口
vim 8000/redis-cluster.conf
将端口都修改为8000,共有7出修改
6启动
redis-server 8000/redis-cluster.conf
7使用ruby语言搭建
redis-trib.rb的命令脚本在redis根目录的src下
a使用create命令可以快速搭建集群
src/redis-trib.rb create 10.9.100.26:8000 10.9.100.26:8001 10.9.100.26:8002
然后这三个就成为集群了,平分了16384个槽道
b登录任意一个节点均可操作
登录集群的客户端命令添加cluster模式的选项
redis-cli -c -p 8000
c输入cluster info显示集群信息
在这里插入图片描述
d输入cluster nodes显示集群信息
在这里插入图片描述
e 添加主节点
src/redis-trib.rb add-node 10.9.100.26:8003 10.9.100.26:8000 。这样8003也成为主节点了。
f添加从节点
格式:add-node new_host:new_port existing_host:existing_port --slave --master-id
例如:src/redis-trib.rb add-node 10.9.100.26:8004 10.9.100.26:8000 --slave --master-id ce1df9a84d11a1bdce289cb2ec9547fc11f47915
意思是把8004挂到8000这个集群中,成为最后那个id的从节点,这个id是8001的id。

重新创建一主一从的脚本(停删启建)
for port in {8000…8005};do redis-cli -c -p $port shutdown;done;
rm -rf dump*;
rm -rf appendonly*;
rm -rf nodes*;
for port in {8000…8005};do redis-server $port/redis-cluster.conf;done;
echo yes|./src/redis-trib.rb create --replicas 1 10.42.82.163:8000 10.42.82.163:8001 10.42.82.163:8002 10.42.82.163:8003 10.42.82.163:8004 10.42.82.163:8005;

–replicas <整数参数>:表示当前集群以主从结构搭建,主从的个数判断有参数决定.1表示每个主节点下至少挂接一个从节点

4、操作
springboot整合JedisCluster

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
@Configuration
@ConfigurationProperties(prefix="redis.cluster")
public class RedisClusterConfig {
	private List<String> nodes;//{"8000","8001","8002"}
	private Integer maxTotal;
	private Integer maxIdle;
	private Integer minIdle;
	@Bean
	public JedisCluster initJedisCluster(){
		//收集节点信息
		Set<HostAndPort> set=new HashSet<HostAndPort>();
		for(String node:nodes){
			//node="10.9.104.184:8000";
			String host=node.split(":")[0];
			int port=Integer.parseInt(node.split(":")[1]);
			set.add(new HostAndPort(host, port));
		}
		//创建配置对象
		GenericObjectPoolConfig config=new GenericObjectPoolConfig();
		config.setMaxTotal(maxTotal);
		config.setMaxIdle(maxIdle);
		config.setMinIdle(minIdle);
		//创建cluster对象返回
		return new JedisCluster(set,config);
	}
	getter&&setter
}

五、其他

1、依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-redis</artifactId>
	<version>1.4.7.RELEASE</version>
</dependency>

2、application.properties文件内容

redis.cluster.nodes=10.9.104.184:8000,10.9.104.184:8001,10.9.104.184:8002
redis.cluster.maxTotal=200
redis.cluster.maxIdle=8
redis.cluster.minIdle=3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值