Redis

2.3.1Redis主要作用
说明:缓存主要的目的是降低客户访问物理设备的频次.保护了真实的后台数据库.
在这里插入图片描述
2.3.2缓存设计原理
1.缓存的数据结构采用k-v K必须唯一
2.要想让缓存执行的速度更快,采用C语言编程.
3.缓存应该运行在内存中.
4.为了防止缓存数据的丢失,应该将数据定期持久化到磁盘中
5.为了防止内存泄露,定期清理内存空间. LRU算法 LFU算法

2.3.3Redis介绍
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
执行速度: 读速度 11.2万次/秒 写速度8.6万/次 平均10万次/秒

2.3.4Redis安装和下载

http://www.redis.cn/

2.3.4.1上传安装文件
在这里插入图片描述
2.3.4.2解压Redis文件

命令:tar -xvf redis-5.0.4.tar.gz

2.3.4.3修改文件名称
在这里插入图片描述
2.3.4.4编译和安装
说明:在redis的根目录中执行下列命令
命令: make
在这里插入图片描述
安装:make install
在这里插入图片描述
2.3.5修改redis.conf
1.修改IP绑定
在这里插入图片描述
2.关闭保护模式
在这里插入图片描述
3.开启后台启动
在这里插入图片描述
2.3.6Redis入门命令
1.启动redis指令
redis-server 当前控制台会被占用,用户体验不友好.
redis-server redis.conf
redis.conf中需要进行后台启动的配置.
2.客户端操作
进入客户端 redis-cli -p 6379
退出客户端 exit 或者 ctrl+c 或者 quit
3.关闭redis redis-cli -p 6379 shutdown

1Redis常规命令
1.1Redis客户端安装
1.双击rdm文件运行.
在这里插入图片描述
2.链接服务器
在这里插入图片描述
3.链接测试
在这里插入图片描述
1.2Redis命令
1.1.1String类型

命令	           说明	                     案例
set	添加key-value	            	set username admin
get	根据key获取数据	         	get username
strlen	获取key的长度	 		strlen key
exists	判断key是否存在			exists name 
返回1存在  0不存在
del	删除redis中的key				del key
Keys	用于查询符合条件的key	keys * 查询redis中全部的key
keys n?me 使用占位符获取数据
keys nam* 获取nam开头的数据   
mset	赋值多个key-value	mset key1 value1 key2 value2 key3 value3 
mget 	获取多个key的值	mget key1 key2
append	对某个key的值进行追加	append key value
type	检查某个key的类型	type key
select	切换redis数据库	select 0-15 redis中共有16个数据库
flushdb 	清空单个数据库	flushdb
flushall	清空全部数据库	flushall
incr	自动加1	incr key
decr	自动减1 	decr key
incrby	指定数值添加	incrby 10
decrby	指定数值减	decrby 10
expire	指定key的生效时间 单位秒	expire key 20 
key20秒后失效
pexpire	指定key的失效时间 单位毫秒	pexpire key 2000
key 2000毫秒后失效
ttl	检查key的剩余存活时间	ttl key
persist	撤销key的失效时间	persist key

1.1.2Hash类型
说明:可以用散列类型保存对象和属性值
例子:User对象{id:2,name:小明,age:19}

命令	说明	案例
hset	为对象添加数据	hset key field value
hget	获取对象的属性值	hget key field
hexists	判断对象的属性是否存在	HEXISTS key field
1表示存在  0表示不存在
hdel	删除hash中的属性	hdel user field [field ...]
hgetall	获取hash全部元素和值	HGETALL key
hkyes	获取hash中的所有字段	       HKEYS key
hlen	获取hash中所有属性的数量	hlen key
hmget	获取hash里面指定字段的值	hmget key field [field ...]
hmset	为hash的多个字段设定值	hmset key field value [field value ...]
hsetnx	设置hash的一个字段,只有当这个字段不存在时有效	HSETNX key field value
hstrlen	获取hash中指定key的长度	HSTRLEN key field
hvals	获取hash的所有值	HVALS user

1.1.3List类型
说明:Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据.
List集合可以当做队列使用,也可以当做栈使用
队列:存入数据的方向和获取数据的方向相反
栈:存入数据的方向和获取数据的方

命令	说明	案例
lpush	从队列的左边入队一个或多个元素	LPUSH key value [value ...]
rpush	从队列的右边入队一个或多个元素	RPUSH key value [value ...]
lpop	  从队列的左端出队一个元素	LPOP key
rpop	从队列的右端出队一个元素	RPOP key
lpushx	当队列存在时从队列的左侧入队一个元素	LPUSHX key value
rpushx 	当队列存在时从队列的右侧入队一个元素	RPUSHx key value
lrange	从列表中获取指定返回的元素	  LRANGE key start stop
  Lrange key 0 -1 获取全部队列的数据
lrem	从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作:
count > 0: 从头往尾移除值为 value 的元素。
count < 0: 从尾往头移除值为 value 的元素。
count = 0: 移除所有值为 value 的元素。	 LREM list -2 “hello” 会从存于 list 的列表里移除最后两个出现的 “hello”。
需要注意的是,如果list里没有存在key就会被当作空list处理,所以当 key 不存在的时候,这个命令会返回 0。
Lset 	设置 index 位置的list元素的值为 value	LSET key index value

1.1.4Redis事务命令
说明:redis中操作可以添加事务的支持.一项任务可以由多个redis命令完成,如果有一个命令失败导致入库失败时.需要实现事务回滚.

命令	     说明	                                      案例
multi	标记一个事务开始	              127.0.0.1:6379> 
                                                            MULTI
                                                            OK
exec	执行所有multi之后发的命令	127.0.0.1:6379> 
                                                             EXEC
                                                              OK
discard	    丢弃所有multi之后发的命令	

1.3Redis入门案例
1.3.1添加jar包
spring整合redis

	<dependency>
		<groupId>redis.clients</groupId>
		<artifactId>jedis</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.data</groupId>
		<artifactId>spring-data-redis</artifactId>
	</dependency>

1.3.2编辑测试类

/**
 * redis入门案例
 * host: redis的IP地址
 * port: redis的端口号
 */
@Test
public void testString() {
	
	Jedis jedis = new Jedis("192.168.226.128", 6379);
	jedis.set("name","小鸡吃米图");
	String value1 = jedis.get("name");
	System.out.println(value1);
	
	jedis.set("name", "小鸡炖蘑菇");
	String value2 = jedis.get("name");
	System.out.println(value2);
}

//测试数据是否允许修改
@Test
public void testString2() {
	Jedis  jedis = new Jedis("192.168.226.128", 6379);
	//如果key已经存在.则不允许赋值.
	jedis.setnx("1909", "今天周三!!!");
	jedis.setnx("1909", "今天周四!!!");
	System.out.println(jedis.get("1909"));
}

/**
 * 为数据添加超时时间并且支持原子性操作
 * @throws InterruptedException 
 */
@Test
public void testString3() throws InterruptedException {
	Jedis  jedis = new Jedis("192.168.226.128", 6379);
	jedis.set("eat", "随便!!!!!");
	//int a = 1/0;  违反了原子性操作!!!!
	jedis.expire("eat", 10);
	Thread.sleep(2000);
	System.out.println(jedis.ttl("eat"));
	
	//为数据添加超时时间,并且同时完成赋值操作.
	jedis.setex("eat", 10, "吃 ..... 随便吧!!!!");
	System.out.println(jedis.get("eat"));
}

/**
 * 1.保证数据不被修改
 * 2.赋值操作与添加超时时间的操作是原子性的
 * 
 * 问题:  nx方法和ex方法 不能同时执行.
 * 
 * params:
 * 		XX:允许覆盖
		NX:不允许覆盖
		PX:毫秒
		EX:秒
 */
@Test
public void testString4() {
	SetParams setParams = new SetParams();
	setParams.nx().ex(10);
	Jedis  jedis = new Jedis("192.168.226.128", 6379);
	jedis.set("1909","您好redis", setParams);
	jedis.set("1909","XXXXXXXXX", setParams);
	System.out.println(jedis.get("1909"));
	}

1.3.3测试Hash类型

private Jedis jedis;
@BeforeEach
public void init() {
	jedis = new Jedis("192.168.226.128", 6379);
}

//一般使用hash存储对象.
@Test
public void testHash() {
	jedis.hset("person", "id", "200");
	jedis.hset("person", "name", "tomcat");
	
	Map<String,String> map = new HashMap<>();
	map.put("id", "2000");
	map.put("name", "伊朗你很厉害");
	map.put("age", "180");
	jedis.hset("student", map);
	System.out.println(jedis.hvals("person"));
	System.out.println(jedis.hgetAll("student"));
}

1.3.4编辑测试List集合

@Test
public void testList() {
	jedis.lpush("list", "1","2","3");
	System.out.println(jedis.rpop("list"));
}

1.3.5测试事务控制

 @Test
public void testTx() {
	//1.开启事务
	Transaction transaction = jedis.multi();
	try {
		//2.进行业务操作
		transaction.set("a", "aa");
		transaction.set("b", "bb");
		transaction.set("c", "cc");
		//3.事务提交
		transaction.exec();
	} catch (Exception e) {
		//4.事务回滚
		transaction.discard();
	}
}

1.1Redis持久化策略

1.1.1发现现象

说明:redis的数据运行在内存中,如果服务器宕机.则内存数据全部丢失.
但是发现.redis重启之后数据依然存在.redis自身有持久化机制.

1.1.2Redis持久化策略
说明:redis根据配置文件中指定的持久化策略,定期将内存数据保存到磁盘中.当服务器重启时,首先会根据配置文件中持久化文件的名称,实现内存数据的恢复.

1.1.3RDB模式
特点说明:
1.RDB模式是Redis的默认的持久化策略.
2.RDB模式可以实现"定期"持久化. 可能会丢失数据.
3.RDB模式持久化时,记录的是内存数据的快照,每次只保留最新的记录. 持久化文件相对较小. 恢复数据速度更快.

1.1.3.1持久化命令
命令1: save 立即持久化,程序可能会陷入阻塞.
命令2: bgsave 后台持久化, 当程序不忙时,进行持久化操作.
在这里插入图片描述
1.1.3.2持久化操作配置文件

1.持久化策略

save 900 1 900秒内,如果更新1次redis时,持久化一次
save 300 10 300秒内,如果更新10次,则持久化一次.
save 60 10000 60秒 更新了10000次.
save 1 1 该配置性能较低.

2.持久化文件名称
dbfilename dump.rdb 253行
3.持久化文件目录
dir ./ 程序运行的当前目录. 目录公用的.

1.1.4AOF模式
特点:
1.AOF模式是关闭的,如果使用,需要手动的开启.
2.AOF模式可以实现实时持久化操作. 可以保证数据不丢失.
3.AOF模式持久化时,记录用户的操作过程.并且将过程追加到持久化文件中.AOF持久化文件相对较大.实现数据恢复速度较慢.
4.如果AOF模式和rdb模式同时存在,以aof模式为主.

1.1.4.1AOF模式的配置
1.开启持久化方式
2.配置持久化文件名称
在这里插入图片描述
1.1.4.2持久化策略
appendfsync always 实时异步持久化.
appendfsync everysec 每秒持久化一次.
appendfsync no 自己不主动持久化.

1.1.5持久化文件实际使用策略
使用redis集群模式.
Redis主机使用RDB模式(效率高).从机使用AOF模式(保证数据安全).

1.2Redis中内存策略

1.2.1需求说明
Redis中的数据都保持在内存中,如果不定期清理则必然会导致内存溢出.
必然使用算法实现定期清理内存.

1.2.2LRU算法
LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。

1***.2.3LFU算法***
说明: redis5.0以后的版本才有LFU算法.
LFU(least frequently used (LFU) page-replacement algorithm)。即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。

1.2.4Redis内存策略设置

1.volatile-lru    设定超时时间的数据采用lru
2.allkeys-lru     所有数据采用lru算法删除数据
3.volatile-lfu 	设定超时时间的数据采用lfu算法
4.allkeys-lfu     所有数据采用lfu算法.
5.volatile-random  设定超时时间的数据采用随机算法
6.allkeys-random   所有数据采用随机算法.
7.volatile-ttl     设定超时时间数据采用ttl算法
8.noeviction       默认策略 不删除数据.如果内存溢出则报错通知使用者.

内存优化策略的修改:
在这里插入图片描述
1.3Redis分片机制

1.3.1单台redis存在问题
1.如果redis服务器宕机,则整体运行出现问题.
2.由于业务需要,需要使用大量的内存空间 来实现数据的缓存.

1.3.2redis分片说明
业务说明:由于单台redis不能保存海量的内存数据,可以使用多台redis共同保持数据.并且每台redis的内存数据都不相同.

1.3.3Redis分片实现
搭建策略: 6379/6380/6381
复制多个配置文件:
在这里插入图片描述

2.修改端口号 各自修改对应的端口号
在这里插入图片描述
3.启动redis

redis-server 6379.conf
redis-server 6380.conf
redis-server 6381.conf

在这里插入图片描述
1.3.4Redis分片入门案例

/**
 * 1.实现redis分片操作
 */

@Test
public void testShards() {
	List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
	shards.add(new JedisShardInfo("192.168.226.128", 6379));
	shards.add(new JedisShardInfo("192.168.226.128", 6380));
	shards.add(new JedisShardInfo("192.168.226.128", 6381));
	ShardedJedis jedis = new ShardedJedis(shards);
	
	//用户操作redis
	jedis.set("1909", "您好Redis分片");
	System.out.println(jedis.get("1909"));
}

1.4Hash 一致性算法

1.4.1Hash一致性说明
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系 [1] 。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。

概念: 对相同的数据进行hash ,那么值必然相同.
知识回顾: 给定未知数x 经过F(x) 得到唯一确定的y的工程
取值范围:
在这里插入图片描述

1.4.2均衡性
说明:当节点出现负载不均的现象时,采用虚拟节点方式实现数据的平衡.

1.4.3单调性
说明:当节点修改时,节点中的数据可以实现自动的数据迁移.
Redis特殊情况: redis中的节点只能新增.尽量不要减少节点.否则出现数据丢失现象.

1.4.4分散性
分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据
了解:由于分布式的部署,程序不能使用全部的内存空间.原来一个key只有一个位置.但是由于分散性.可能导致 一个key有多个位置.

A: 3倍内存
B: 2倍内存
以后使用服务器时,最好使用全部的内存空间.

1.4.5关于分片说明
说明:使用redis分片机制,主要的目的实现内存的扩容.

1.5SpringBoot整合redis分片
1.5.1编辑Properties配置文件

#配置redis分片
redis.nodes=192.168.226.128:6379,192.168.226.128:6380,192.168.226.128:6381	

1.5.2编辑RedisConfig配置类

//标识配置类信息
@Configuration
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {

@Value("${redis.nodes}")
private String nodes; //node,node,node


//配置redis分片功能.
@Bean
@Scope("prototype")
public ShardedJedis shardedJedis() {
	List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
	String[] arrayNode = nodes.split(",");
	//node=ip:port
	for (String node : arrayNode) {
		String host = node.split(":")[0];
		int port = 
				Integer.parseInt(node.split(":")[1]);
		JedisShardInfo info = 
				new JedisShardInfo(host, port);
		shards.add(info);
	}
	
	return new ShardedJedis(shards);
}

}

1.5.3修改AOP配置
在这里插入图片描述
1.6Redis哨兵机制
1.6.1哨兵机制说明
说明:可以引入哨兵机制,实现redis服务器高可用.但是实现高可用的前提条件实现数据的主从同步.
1.6.2部署哨兵服务器
说明:准备3台redis,并且分别修改各自端口号信息.
在这里插入图片描述
分别启动3台redis.
在这里插入图片描述
1.6.3实现主从配置
1.检查默认条件下 主机状态
在这里插入图片描述
1.6.4挂载策略定义
规定: 6379主机 6380/6381当从机.
命令: slaveof 主机IP 主机端口
Slaveof 192.168.226.128 6379
在这里插入图片描述
结果:
最终将6380/6381 挂载到6379上.在主机中执行set指令.检查从机是否正常同步数据.
检查主机状态:
在这里插入图片描述
1.6.5哨兵工作原理.
在这里插入图片描述
实现原理:
1.当哨兵服务启动时,首先监控主机的状态.同时获取主机的详细信息.
2.哨兵会通过心跳检测机制,定期检查主机的状态.
3.如果发现主机超过3次没有响应.则断定主机宕机.开启推选机制.
4.当哨兵推选一台从机当选主机时.其他的服务器都当该主机的从机.

1.6.6编辑哨兵的配置文件

复制哨兵的配置文件
命令: cp sentinel.conf sentinel

1.6.6.1关闭保护模式
在这里插入图片描述
1.6.6.2开启后台启动
在这里插入图片描述
1.6.6.3配置哨兵监听
1.监听主机的IP地址 端口 选举的票数
在这里插入图片描述
1.6.6.4修改哨兵宕机选举的时间
在这里插入图片描述
1.6.6.5修改哨兵选举失效的时间
在这里插入图片描述
1.6.7哨兵高可用测试
1.命令: redis-sentinel sentinel.conf
2.检查哨兵服务项:
在这里插入图片描述
3.高可用测试
当主机宕机之后,检查哨兵是否会选举新的主机.
在这里插入图片描述
2.重启主机.测试是否正常
在这里插入图片描述
1.6.8问题说明
如果哨兵配置有误,按照下列步骤执行.
1.将redis的全部的服务关闭.
ps -ef |grep redis
kill -9 PID PID PID PID
2.将redis根目录中的sentinel文件删除 之后重新配置即可.

1.6.9Redis入门案例

/**
 * 	哨兵测试
 * 	1.配置redis的节点数据集合
 *  2.利用哨兵机制连接redis节点.
 *  3.用户通过哨兵 实现缓存操作.
 *  
 *  参数1: masterName
 */
@Test
public void testSentinel() {
	//配置哨兵的信息
	Set<String> sentinels = new HashSet<>();
	sentinels.add("192.168.226.128:26379");
	JedisSentinelPool pool = 
			new JedisSentinelPool("mymaster", sentinels);
	Jedis jedis = pool.getResource();
	jedis.set("1909","哨兵搭建成功!!!!");
	System.out.println(jedis.get("1909"));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值