4.4 布隆过滤器
4.4.1 介绍
布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。
4.4.2 计算机进制换算
1字节 = 8比特
1kb = 1024字节
1mb = 1024kb
4.4.3 业务场景
假设数据库中有1000万数据,每条记录大约2kb 如果该数据都是热点数据,则需要多大的内存空间进行存储? 19G数据!!!
问题: 能否优化内存数据的存储呢??? 尽可能少占用内存空间.
想法: 如果使用1个**bit(01)**代表一个数据, 问占用多大空间 1.19M
4.4.4 布隆过滤器原理
核心1: 很长的二进制向量(有方向的叫向量,无方向的叫标量)
核心2: 多个hash函数
解决问题: 校验数据是否存在!!!
1).数据加载过程
2).数据校验
3).存在问题
好的布隆算法可以将误判率 降低到 < 0.03%
5 Redis分片机制
5.1 为什么需要分片
说明: 如果有海量的内存数据需要保存,但是都把数据保存到1个redis中,查询的效率太低.如果这台redis服务器宕机,.则整个缓存将不能使用.
解决方案: 采用redis分片机制.
注意:
6379,6380,6381三个redis数据库存储的数据是不是一样的?
答案肯定是不一样的,如果一样的那么我们分片机制还有意义了吗
5.2 Redis分片搭建
5.2.1 准备配置文件
5.2.2 修改端口号
说明: 分别将6379/6380/6381的端口号进行配置
vim 6380.conf
:/port 检索端口号 然后进行修改
:wq进行保存
5.2.3 启动三台redis
[root@localhost shards]# redis-server 6379.conf & redis-server 6380.conf & redis-server 6381.conf &
校验redis
5.2.4 redis分片入门案例
/**
* 3台redes key如何存储?? 79/80/81
*/
@Test
public void testShards(){
List<JedisShardInfo> shards = new ArrayList<>();
shards.add(new JedisShardInfo("192.168.126.129", 6379));
shards.add(new JedisShardInfo("192.168.126.129", 6380));
shards.add(new JedisShardInfo("192.168.126.129", 6381));
ShardedJedis shardedJedis = new ShardedJedis(shards);
shardedJedis.set("shards", "redis分片机制");
System.out.println(shardedJedis.get("shards"));
}
5.3 一致性hash算法
5.3.1 介绍
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。
核心知识:
1. 一致性hash解决了数据与节点的映射关系(数据归谁管理)
2. 节点增加/减少时,数据可以弹性伸缩.
5.3.2 一致性hash算法原理
5.3.3 特性-平衡性
说明: 平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题
解决策略: 引入虚拟节点
5.3.4 特性-单调性
②单调性是指在新增或者删减节点时,不影响系统正常运行。
说明: 无论节点增/减,数据都能找到与之匹配的node进行数据的挂载.
5.3.5 特性-分散性
③分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据 [4] 。
谚语: 鸡蛋不要放到一个篮子里.
百度原理图1:
百度原理图2:
5.4 SpringBoot整合Redis分片
5.4.1 编辑配置文件
#单台redis配置
#redis.host=192.168.126.129
#redis.port=6379
#Redis分片机制
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381
5.4.2 编辑配置类
package com.hc.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import java.util.ArrayList;
import java.util.List;
@Configuration //标识为一个配置类,一般整合第三方
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
@Value("${redis.nodes}")
private String nodes;//node,node,node
@Bean
public ShardedJedis shardedJedis(){
List<JedisShardInfo> shards=new ArrayList<>();
String[] nodeArray=nodes.split(",");
for(String node:nodeArray){//node=host:port
String host=node.split(":")[0];
int port=Integer.parseInt(node.split(":")[1]);
JedisShardInfo info=new JedisShardInfo(host,port);
shards.add(info);
}
//2.编辑redis配置文件,调整链接数量
/*JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMinIdle(10); //最小空闲数量
jedisPoolConfig.setMaxIdle(40); //最大的空闲数量
jedisPoolConfig.setMaxTotal(1000);
ShardedJedisPool shardedJedisPool =
new ShardedJedisPool(jedisPoolConfig, shards);
return shardedJedisPool.getResource();*/
return new ShardedJedis(shards);
}
// @Value("${redis.host}")
// private String host;
// @Value("${redis.port}")
// private Integer port;
//
// @Bean //将该方法的返回值,交给Spring容器管理
// public Jedis jedis(){
//
// return new Jedis(host,port);
// }
}
5.4.3 修改RedisAOP
注意事项:如果6379或者其中一台redis服务器宕机,我们再去访问manage.hc.com然后查询缓存,会发现找不到并且控制台报错,连接超时
6.Redis哨兵机制
6.1 关于Redis分片特点
Redis分片可以实现内存数据的扩容,但是如果节点宕机则直接影响程序的运行.
问题关键: 如果节点宕机,需要实现高可用.
6.2 Redis数据同步配置
6.2.1 复制目录
说明: 将shards目录复制 并且改名为sentinel
删除sentinel目录下无用的持久化文件
6.2.2 启动3台redis
说明: 1.删除原有的持久化文件
2.启动3台redis
6.2.3 主从结构搭建
- 6379 主机
- 6380/6381 从机
2.主从挂载命令
slaveof 192.168.126.129 6379
6.3 Redis哨兵实现
6.3.1 哨兵原理
说明:
1.当哨兵启动时,会链接redis主节点,获取所有节点的相关信息.
2.当哨兵通过心跳检测机制 PING -PONG 命令校验服务器是否正常.
3.如果哨兵连续3次发现服务器没有响应,则断定当前主机宕机.
4.之后由哨兵采用随机算法挑选其中的一个从机当选主机.并且其他的节点当做新主机的从.
6.3.2 配置哨兵服务
1).复制文件
cp sentinel.conf sentinel/
2).关闭保护模式
3).开启后台运行
4).哨兵监控
5).修改宕机时间
6.3.3 哨兵命令
1.启动 redis-sentinel sentinel.conf
2.关闭哨兵 ps -ef |grep redis
kill -9 PID号
6.3.4 哨兵高可用测试
1).关闭6379主机,检查从机是否当选主机
2).检查从机的配置文件 是否以后关联了主机
最后一行代表 我是谁的从
如果搭建错误,.则需要删除最后一条主从关系.,之后重启服务器.重新搭建.
6.4 SpringBoot整合哨兵
6.4.1 入门案例
/**
* 测试哨兵API
*/
@Test
public void testSentinel(){
Set<String> sets = new HashSet<>();
sets.add("192.168.126.129:26379");
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(10);
poolConfig.setMaxIdle(40);
poolConfig.setMaxTotal(1000);
JedisSentinelPool pool = new JedisSentinelPool("mymaster",sets,poolConfig);
Jedis jedis = pool.getResource();
jedis.set("AAA", "您好Redis");
System.out.println(jedis.get("AAA"));
jedis.close();
}
6.5 关于Redis分片/哨兵总结
1.分片作用: 扩大内存实现海量数据数据的存储. 缺点: 没有实现高可用
2.哨兵作用: 实现了节点的高可用. 缺点: 1.哨兵不能实现扩容 2.哨兵本身没有高可用
想法: 能否有一种机制 既可以实现内存扩容,又可以实现高可用(不需要第三方)
7.Redis集群规则
7.1关于集群搭建错误说明
1).关闭redis集群
2).删除多余的配置文件
3).重启redis
4).搭建redis集群