【Redis】Redis 非关系型数据库 安装、配置、使用(全集)

目录

Redis

第一章

1、什么是redis

2、安装redis

1-7

8

3、redis使用

第二章

1、redis的使用

1、使用方式

2、使用Java代码使用redis

3、优化连接redis

2、五种数据类型

常用命令

string

hash

list

set

zset

不同数据类型存、取、遍历的方法

3、redis在项目中使用

示例

1

2

3

4

5

6-7

第三章

1、redis的作用

存在问题

1、高并发

2、缓存击穿

3、缓存雪崩

4、缓存穿透

总结

2、redis数据持久化策略

数据持久化策略有两种

方式1

方式2

区别

3、redis中的主从复制

配置步骤

第四章

1、redis的集群配置

1、配置要求

2、判断失败标准

3、配置原理

4、配置完成数据如何存储

2、准备工作

3、构建redis集群

1-5

6-11

4、测试集群

5、Java代码访问集群

示例1:与spring无关,单独访问集群

示例2:在spring中使用集群


Redis

第一章

1、理解redis的基本概念 2、安装、配置redis 3、redis的使用

1、什么是redis

redis是一种非关系型数据库,它用于存储数据提供给程序使用(c语言编写)
​非关系型数据(NoSql)它的特点:它没有数据表的概念了,它存放的数据是存放在内存中的
典型的非关系型数据库,主要有:redis,mongodb redis它是采用键、值对的方式,将数据存放在内存中
​关系型数据库:   sqlserver,mysql,oracle这些都是关系型数据库它们的特点:数据是以数据表的形式进行存储,数据是存放在数据库系统中

image-20230818105340889

非关系型数据库从内存中加载数据,速度会更快
​
关系型数据库的数据是存放在数据库系统中的,它们会更安全
​
@@@@@@在实际应用中,项目一般会将关系型数据库与非关系型数据库结合使用
​redis这种非关系型数据库,主要是作为缓存使用,这样可以避免频繁查询数据库,导致数据库压力过大
​

2、安装redis

步骤

1-7
@@@@@redis可以在windows中使用,也可以在linux下使用。但一般都会配置到linux下
​
1、下载redis
​
2、将它发布到linux下的 d113
​
3、安装C语言运行环境(REDIS是采用c语言编写的)yum install gcc-c++
​
4、将/d113目录下的redis解压缩 
​tar -xvPf /d113/redis-3.0.0.tar.gz  -C /usr/local/d113/
​
5、进入/usr/local/d113/redis-3.0.0目录cd /usr/local/d113/redis-3.0.0
​
6、构建redismake
​
7、安装redismake install PREFIX=/usr/local/d113/redis
​

image-20230818110507517

8
8、启动redis的服务端1、进入 /usr/local/d113/redis/bin目录 
​cd  /usr/local/d113/redis/bin
​2、准备启动redis服务器(启动有两种方式)
​@@@@@@@@@@前台启动(这种方式启动后,控制台界面就不能再编写其他代码了,需要再打开一个新的控制台窗口写代码)
​./redis-server
​
​@@@@@@@@@后台启动(启动后,界面不会被占用,还可以继续写代码 )-------推荐使用
​1、进入/usr/local/d113/redis-3.0.0将redis.conf文件复制到/usr/local/d113/redis/bin目录中cp /usr/local/d113/redis-3.0.0/redis.conf  /usr/local/d113/redis/bin
​2、进入usr/local/d113/redis/bin目录,修改redis.conf配置,指定后台启动redis找到配置文件  daemonize no修改为  daemonize yes
​3、进入usr/local/d113/redis/bin执行./redis-server redis.conf3、启动客户端连接redis服务器1、进入目录 /usr/local/d113/redis/bin2、执行  ./redis-cli
​4、退出redis的客户端: exit停止redis的服务器:1、查看redis进程ps -ef | grep redis
​2、杀死进程kill -9 进程号
​
​

3、redis使用

@@@@@@redis在编辑文件时,查找指定内容的快捷键:
​1、vi 文件
​2、按下/输入要查找的内容,回车
​3、按字母i,开始编辑
​4、如果还要查找其他内容,可以先按esc 退出编辑模式,再按下/输入要查找的内容,回车
​5、保存退出

第二章

1、redis中的五种数据类型 2、redis的使用 3、redis的持久化策略 4、redis中的主从复制

前情摘要

@@@@@@@@@@@@@@@@@@@启动redis分为前台启动与后台启动
​
后台启动redis的步骤:
​
1、进入/usr/local/d113/redis/bin
​
2、后台启动redis./redis-server redis.conf
​
3、查看redis是否启动成功ps -ef | grep redis
​
4、如果要停止rediskill -9 进程号@@@@@@@@在编辑文件时,要快速查找指定内容 
​
1、vi 文件名
2、输入/要查询的内容,然后回车
3、找到内容后按字母i进行编辑
4、如果编辑完了,要再查找其他内容,只需要按esc退出编辑模式,再继续输入/内容

1、redis的使用

1、使用方式
@@@@@@@@@@@操作redis的方式主要有三种:
​
方式1、通过redis的客户端访问redis服务器1、在/usr/local/d113/redis/bin目录下输入下列命令即可连接redis客户端./redis-cli
​2、退出redis客户端exit
​
​
方式2:用一个桌面管理工具,在windows中可以直接访问linux下的redis@@@@如果要用桌面管理工具体或者java连接redis都必须将redis的6379端口号在linux的防火墙中注册
​firewall-cmd --zone=public --add-port=6379/tcp --permanentfirewall-cmd --reload
​
​
方式3:在java代码中通过jedis与redis建立连接@@@@@@@@@jedis:用java代码连接redis的技术
2、使用Java代码使用redis

步骤

    1、创建工程2、导入下列依赖<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.7.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.7.0</version></dependency>
​3、编写代码 //创建jedisJedis jedis = new Jedis("192.168.47.128",6379);//存数据//jedis.set("msg2","abc");//关闭jedisjedis.close();
​@@@@@@这种方式连接redis性能不好,它在连接redis的时候需要自己创建连接,用完后,连接又会被销毁,这样会导致频繁创建、销毁连接,会消耗更多资源降低程序的性能
​为了解决该问题,在连接redis时,我们都需要配置连接池,配置jedis连接池以后,当需要使用连接时,不需要自己创建,只需要从连接池中获得连接,用完以后,关闭资源,连接并不会真的释放。它会回到连接池,其他用户可以继续使用,这样可以避免频繁创建、销毁连接
3、优化连接redis
@@@@@@@@@@@@@采用连接池的方式操作redis//创建连接池的配置对象,用于设置连接池配置信息JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();//指定连接池的最小闲置连接数--------连接池最少要保证有多个闲置连接,如果没有就会马上自动创建jedisPoolConfig.setMinIdle(50);//指大最大闲置连接数jedisPoolConfig.setMaxIdle(100);//设置最大连接数jedisPoolConfig.setMaxTotal(200);//由于用完的连接并不会释放,会回到连接池,设置多余闲置连接的销毁时间jedisPoolConfig.setEvictorShutdownTimeoutMillis(3000);//设置等待连接的超时时间jedisPoolConfig.setMaxWaitMillis(3000);//创建jedis连接池JedisPool jedisPool = new JedisPool(jedisPoolConfig,"192.168.47.128",6379);//通过连接池获得jedisJedis jedis = jedisPool.getResource();//操作redisjedis.set("msg3","china");//关闭jedis(不是真的关闭,只是让用完的连接回到连接池中)jedis.close();

2、五种数据类型

redis中的数据类型有五种:1、string-----------------字符串类型2、hash-------------------散列类型3、list-------------------列表类型4、set--------------------无序集合类型5、zset-------------------有序集合类型
常用命令
查看当有redis中有哪些键       keys *清空redis中的所有数据flushall删除键 del 键判断当前键对应的数据类型type 键给键设置过期时间(秒)如果不设置,键将永远存在expire 键  10注意:键必须要先存在,才能设置。键默认是永不过期查看键的过期时间ttl 键 -1:永不过期-2:键已经过期18:当前键还可以存活18秒
string
@@@@@@@@@@string-----------------字符串类型1、存数据set 键  值set msg hello2、通过键取值 get 键get msg3、一次存放多键值对mset 键1 值1 键2 值2mset k1 aa k2 bb4、一次通过多个键取值mget 键1 键2mget k1 k25、判断是否存在某一个键(存在返回1,不存在返回0)exists 键6、删除某一个键(成功返回1,失败返回0)del 键@@@@@@@@@@@如果当前键对应的值是一个数值,则可以使用下列这一组命令incr 键---------------------让当前的数值加1decr 键---------------------让当前的数值减1incrby 键  5--------------- 当前值上加5decrby 键  5--------------- 当前值上减5字符串类型的数据在存放数据时,如果键已经存在,值将会被覆盖

image-20230818175654607

hash
@@@@@@@@@@@@@hash散列类型它存放的值是一个map类型1、存数据:hset 键 字段 值hset stu id   1hset stu name jackhset stu score 100@@@@@散列结构在存放数据时,只有键与字段名都相同的时候,值才会被覆盖。如果仅仅是键相同字段名不同,它执行追加2、取数据hget 键  字段hget stu idhget stu namehget stu score3、一次性存放多个字段hmset 键  字段1 值1 字段2 值2hmset s2 id 1 name jack score 994、一次性取多个字段hmget 键 字段1 字段2hmget s2 id name score5、获得键里面包含的所有字段名hkeys 键6、获得键中包含所有的字段值kvals 键7、判断键中是否包含某一个字段hexists 键 字段名8、删除某一个字段hdel  键 字段名
list
@@@@@@@@@@list列表类型它是一种双向链表结构,它存放数据时,可以从两头进存放特点:1、有顺序2、可以有重复元素1、存放数据(从左向右存放)leftlpush 键  值1 值2 值3lpush list1  a  b  c输出:c b a2、从右向左存放 rightrpush 键  值1 值2 值3rpush list1  111  222  333@@@@键存在,也不会覆盖,只是追加数据输出:c b a 111 222 3333、取列表中最左侧的数据(取一次,列表中就会少一个数据)lpop 键4、取列表中最右侧的数据(取一次,列表中就会少一个数据)rpop 键5、遍历列表的所有数据lrange 键  0 -1lrange list1 0 -1
set
@@@@@@@@set无序集合类型特点:1、没有顺序2、不能有重复元素1、存数据sadd 键 值1 值2 值3sadd set1 aaa bbb ccc2、获得所有数据smembers 键smembers set13、判断是否包含某一个值sismember 键 值sismember set1 aaa4、从无序集合中随机获得一个值(获得该值后,这个值就会从集合中移除)spop set1(适合用于抽奖)
zset
@@@@@@@@zset有序集合类型特点:1、有顺序2、不能有重复元素1、存数据zadd 键  分数1 值1   分数2 值2 -------------它在添加数据时必须给每一个值设置一个分数,排序时按分数升序排序zadd zset1  100 andy 80 bruce 90 tom2、查看所有数据(不包含分数),默认是按分数升序排序zrange 键 0 -1zrange zset1 0 -13、查看所有数据(包含分数),默认是按分数升序排序zrange 键 0 -1 withscoreszrange zset1 0 -1 withscores4、查看所有数据(包含分数),按分数降序排序zrevrange 键 0 -1 withscores                zrevrange zset1 0 -1 withscores
不同数据类型存、取、遍历的方法
stringset key valueget keyhashhset key 字段 值hget key 字段listlpush 键 aa bb ccrpush 键 aa bb cclrange 键 0 -1setsadd 键  aaa bbb  cccsmembers  键spop 键zset  zadd 键 分数  值1  分数 值2zrange 键  0 -1zrange 键  0 -1 withscoreszrevrange 键  0 -1 withscores

3、redis在项目中使用

@@@@@@@@redis在项目中的使用redis在项目中主要是作为缓存使用,这样可以在高并发环境下,环境数据库的压力项目中配置了redis后的执行过程:1、当请求到达服务器,查询某一条数据时,系统会首先查询redis缓存中有没有需要数据2、如果缓存中没有需要的数据,系统就会查询数据库,并且把查询到结果放入缓存,然后将查询结果返回给客户端3、下一次当客户端再一次查询该数据时,由于缓存中已存在该数据,系统就会直接返回缓存中的数据,不再查询数据库
示例

<!--具体详情请看:redis_j54_singleton项目 -->

1、导入素材与redis无关
2、@@@加入redis实现功能
1
1、在pom.xml导入下列依赖<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.7.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.7.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.7.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.7.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.7.0</version></dependency>
2
2、添加配置文件 applicationContext-redis.xml<!--1、指定redis配置对象--><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--指定连接池的最小闲置连接数连接池最少要保证有多个闲置连接,如果没有就会马上自动创建--><property name="minIdle" value="50"/><!--最大闲置连接数--><property name="maxIdle" value="100"/><!-- 设置最大连接数--><property name="maxTotal" value="200"/><!--由于用完的连接并不会释放,会回到连接池,设置多余闲置连接的销毁时间--><property name="evictorShutdownTimeoutMillis" value="3000"/><!--设置等待连接的超时时间--><property name="maxWaitMillis" value="3000"/></bean><!--    2、配置连接池--><bean id="jedisPool" class="redis.clients.jedis.JedisPool"><constructor-arg name="poolConfig" ref="jedisPoolConfig"/><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="6379"/></bean>
3
3、修改web.xml加载redis的配置文件<servlet><servlet-name>mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext*.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>mvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
4
4、编写redis的接口public interface JedisClient {public void set(String key,String value);public String get(String key);public void hset(String key,String field,String value);public String hget(String key,String field );public void hdel(String key, String filed);}
5
5、编写Jedis的实现类(单机版)@Componentpublic class JedisClientSingleImpl implements JedisClient {//注入连接池@Autowiredprivate JedisPool jedisPool;@Overridepublic void set(String key, String value) {Jedis jedis = jedisPool.getResource();jedis.set(key,value);jedis.close();}@Overridepublic String get(String key) {Jedis jedis = jedisPool.getResource();String value = jedis.get(key);jedis.close();return value;}@Overridepublic void hset(String key, String field, String value) {Jedis jedis = jedisPool.getResource();jedis.hset(key,field,value);jedis.close();}@Overridepublic String hget(String key, String field) {Jedis jedis = jedisPool.getResource();String value = jedis.hget(key, field);jedis.close();return value;}@Overridepublic void hdel(String key, String filed) {Jedis jedis = jedisPool.getResource();jedis.hdel(key,filed);jedis.close();}}
6-7
6、导入jsonUtil工具类,用于转换Json数据7、修改Service的代码 在查询数据之前,先查询redis,如果有需要的数据,就不再查询数据库@Service
public class PrdServiceImpl implements PrdService {@Autowiredprivate PrdMapper mapper;//注入jedis接口@Autowiredprivate JedisClient jedisClient;@Overridepublic List<Prd> getList() {return mapper.getList();}@Overridepublic Prd findById(String pid) {//首先查询redis中有没有需要的数据String json = jedisClient.hget("redis_j54_singleton", pid);//判断数据是否为null,如果为空,表示缓存中还没有需要的数据,需要到数据库加载if(StringUtils.isEmpty(json)){//为空,表示缓存中还没有需要的数据,需要到数据库加载System.out.println("到数据库加载编号为:"+pid+"的数据");//准备查询数据库Prd prd = mapper.findById(pid);//在返回之前要把它转换成json存放到redisjson = JsonUtils.objectToJson(prd);jedisClient.hset("redis_j54_singleton",pid,json);return prd;}else{//缓存中有需要的数据.需要将Json还原成对象返回System.out.println("到缓存中加载编号为:"+pid+"的数据");Prd prd = JsonUtils.jsonToPojo(json, Prd.class);return prd;}}
}

第三章

1、缓存击穿(缓存穿透、缓存雪崩) 2、redis数据持久化策略 3、redis中的主从复制 4、redis集群的使用

Linux常用命令

编辑文件:vi redis.conf搜索内容:/内容 进入编辑模式: i退出编辑: esc保存:    :wq不保存:   q!查看正在运行的某一个程序(进程)ps -ef | grep 程序名杀死进程 kill -9 进程号解压缩:  tar -xvPf 压缩包名称  -C /usr/local/d113复制文件  cp  文件名 指定路径 复制文件夹  cp  文件名 -r 指定路径 删除文件  rm -rf  文件名重命名   mv 原文件名 新文件名查看ip   ifconfig 新建文件夹   mkdir 文件夹名称查看文件内容  cat    less查看当前文件夹中的所有文件 ls查看当前文件夹中的所有文件(包含隐藏文件) ls -a联网安装软件   yum install  软件名返回上一级  cd ..返回根目录  cd /

1、redis的作用

redis在项目中的主要作用是:作为缓存使用在客户端请求到达服务器后,系统会首先判断缓存中有没有需要的数据,如果没有,系统就会查询数据库,并且把查询到的数据放入到缓存中,然后再返回。当下一次请求,再次到达到服务器,如果检测到缓存中有需要的数据,就会直接返回缓存中的数据,不再走数据库加载,这样可以缓解数据压力。在项目中配置redis缓存后,假设某一个条数据被请求了10000次第1次应该从数据库加载数据剩余的9999次都应该从缓存中加载
存在问题
    问题:当缓存中有数据,请求就会直接返回缓存中的数据,不再走数据库,假设,此时后台的数据被修改了,但由于缓存中有数据,将会导致最新修改的数据无法加载答:当后台某一台数据被修改后,我们可以找到它对应的缓存数据,将该数据从缓存中移除掉
1、高并发
高并发:大量请求同时访问条件:在高并发环境下,有1000个请求访问同一条数据,线程池每次可以并发执行100个线程1、第1批的100个线程,它们一开始并发执行到redis中访问数据,由于redis中没有数据,所有它们得到的结果就是redis中没有需要的数据,这100个线程都要到数据库查询2、这100个线程查询数据库后,每一个线程都会将查询到的对象,存放到redis中3、后面900个请求对应的线程,由于redis中已经有数据了,就直接返回缓存中的数据,不再查询数据库
2、缓存击穿
缓存击穿:大量请求访问同一条数据(热点数据),如果该数据在redis中不存在,但是在数据库中存在,导致大量请求同时访问数据库,这种情况我们称为:“缓存击穿”解决方案:1、设置热点数据永不过期2、设置互斥锁(双重检测锁)

双层检测锁

双重检测锁假设有100个线程并发执行1、在方法中首先查询缓存中有没需要的数据(100个线程会同时查询)2、如果这100个线程没有找到需要数据,它们都要准备查询数据库3、在这100个线程准备查询数据库之前,编写一个同步锁synchronized,在同步锁中每一次只能执行1个线程4、在synchronized中,再查询一次缓存,这100个准备查询数据库的线程,只能一个一个查询5、如果在synchronized中如果能够从缓存中查询到需要的数据,就表示已经有线程查询过数据库,当前线不需要再次查询,直接返回缓存中的数据即可6、如果synchronized中的线程,从缓存中依然查询不到数据,表示这100个线程都还没有查询过数据库,当前线程就要到数据库查询,并且将查询结果放入到缓存,其他线程就返回缓存中的数据即可
3、缓存雪崩
缓存雪崩:缓存中的大量热数据同时到期,导致缓存中的大量数据同时失效,这样大量请求会同时访问数据库,导致数据库压力过大解决方案:1、均匀的给热点数据设置过期时间,不要让它们同时失效
4、缓存穿透
缓存穿透当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。解决方案:缓存穿透的方案,常见的方案有三种。第一种方案,非法请求的限制;第二种方案,缓存空值或者默认值;第三种方案,使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在;
总结
缓存击穿:一个热点数据过期,它在缓存不存在,在数据库存在,会导致并发环境下,大量请求同时访问数据库缓存雪崩:大量热点数据同一时间过期,会导致大量请求同时访问数据库缓存穿透:请求的数据在缓存中不存在,在数据库也不存在,导致无法构建缓存结构,所有请求会频繁访问数据库

2、redis数据持久化策略

redis的持久化策略
问题:redis的数据是存放在缓存中的,但当程序关闭时,缓存会被释放掉,为什么redis的数据不会丢失?答:因为redis有自己的持久化策略。当用户向redis存放数据时,数据是存在内存中的,当程序关闭时,redis默认会将内存中的数据保存到一个名为dump.rdb文件中,此时即使内存被释放,但数据已经存放在dump.rdb文件,当起动redis时,系统又会将dump.rdb中的数据加载到内存中
数据持久化策略有两种
方式1
   方式1:采用一种快照的方式,定时将内存中的数据存放到rdb文件如果修改了redis中的1条数据,系统会在900秒以后,自动存放到dump.rdb文件如果修改了redis中的10条数据,系统会在300秒以后,自动存放到dump.rdb文件如果修改了redis中的10000条数据,系统会在60秒以后,自动存放到dump.rdb文件save 900 1save 300 10save 60 10000问题:如果修改了1条数据,如果关闭redis它会不会马上保存不会保存,会丢失掉希望数据后马上保存,可以执行 save命令即可@@@@@默认情况下redis是采用rdb快照的方式定时存储数据这种方式的缺点时,由于它是定时存储,如果存储时间没有到程序意外终止,将会导致未保存的数据丢失。为了解决这个问题,redis提供了另一种持久化策略
方式2
方式2:采用一种日志的方式即时存储(一般用的也是aof)这种方式会生成一个aof文件,对redis做的任何修改都会马上保存到这个文件中,即使程序意外终止,数据也不会丢失配置方式:1、修改/usr/local/d113/redis/bin/redis.confvi  /usr/local/d113/redis/bin/redis.conf2、修改文件中的一行代码 将  appendonly no 修改为 appendonly yes3、重启redis服务
区别
@@@@@@@Redis持久化策略中的rdb方式与aof方式的区别?答:rdb是采用快照的方式定时存储,它比较节省资源,但可能会导致未保存的数据意外丢失aof是采用日志的方式即时存储,它消耗的资源会比rdb方式更多,但它可以防止数据意外丢失

3、redis中的主从复制

@@@@@@@@@@@如何解决redis的单点故障?单点故障:某一台redis服务无法使用,导致数据无法读取解决方案:配置redis服务器的主从复制(给主机配置从机),主机上的数据,会自动备份到从机。主机如果发生故障,从机可以提供数据
配置步骤
	1、将/usr/local/d113/redis/bin目录复制一份名为bin2bin-----主机bin2----从机cp  /usr/local/d113/redis/bin -r /usr/local/d113/redis/bin22、删除bin2目录下的 rdb与aof文件rm -rf *.rdb    *.aof3、主机不需要进行任何配置4、修改从机的 redis.conf1、进入bin2slaveof 主机的Ip地址  主机的端口号slaveof 192.168.47.128  6379由于在同一台电脑中,多个端口不能冲突,所以要将从机的端口改为6380port 6380
	5、启动从机服务器1、进入bin22、执行命令 ./redis-server redis.conf6、在主机上进行的任何操作,数据都会反映到从机bin是主机bin2是从机7、登录从机的客户端查看数据1、进入bin22、执行命令 ./redis-cli -p 6380@@@@@@@@@@@@@@注意:从机只能读数据,不能写数据

第四章

redis集群的配置及使用

1、redis的集群配置

@@@@我们之前配置的redis是单机版,所有请求需要由一台redis服务器进行处理,当请求的数据量比较大时,该服务器的压力也会比较大
为了解决这个问题,我们可以配置redis集群配置redis服务器集群的好处:1、将原本应该由一台redis主机承受的压力,分散到多台redis主机共同分担,这样可以减少单台redis主机的压力2、配置redis集群,可以让多台redis主机共同处理请求,性能会更快3、配置redis集群后,redis的主机会自动配置从机。当redis主机挂了,它的从机会自动升级成主机可读可写
1、配置要求
@@@@配置redis集群的要求:1、redis的主机数量必须是单数,至少需要配置3台redis主机
2、redis的主机需要配置从机@@@@@@配置redis集群至少需要6台redis服务器,其中3台主机,3台从机
2、判断失败标准
@@@@@@判断redis集群是否失败的标准是什么1、如果集群中主机挂了,它如果没有配置从机。该节点无法访问,集群失败无法使用2、如果集群中有一半以上的主机挂了,即使它们配置了从机,集群也是失败的
3、配置原理
@@@@配置redis集群的原理:通过网络将多台redis服务器连接在一起,共同处理请求,这样可以提升处理请求的效率,减少单台服务的压力
4、配置完成数据如何存储
@@@@配置redis服务器集群后,数据是如何存储的?当配置redis集群中,集群中会产生16384个哈希槽(哈希槽用于具体存储数据),这些哈希槽会均分到每一台主机上,当向redis集群存储数据时,redis存放数据是采用:键值对方式存储的。系统会对键采用一种CRC16算法,将键转换成一个数值,然后系统用这个数值取模16384,会得到一个介于0~16383之间的值,系统会判断这个值对应的哈希槽在哪一台主机上,就会自动切换到主机这些哈希槽范围是:  0~16383假设有三台主机:第一台主机:  0 ~ 5000第二台主机:  5001 ~ 10000第三台主机:  10001~16383

2、准备工作

@@@@@@@配置redis集群前的准备工作:由于redis集群的管理工具是用ruby语言写出来的,所以我们要先配置ruby的环境1、联网安装ruby的环境yum install rubyyum install rubygems2、下载redis集群管理工具redis-3.0.0.gem3、将工具发布到Linux下的/d113目录中4、进入/d113目录执行下列命令安装工具gem install redis-3.0.0.gem5、在/usr/local/d113目录下,创建一个名为:redis-cluster的目录,用于存放redis集群中的所有redis服务器mkdir /usr/local/d113/redis-cluster6、将/usr/local/d113/redis/bin目录复制一份到/usr/local/d113/redis-cluster,同时命名为7001(它就是一台redis服务器)cp /usr/local/d113/redis/bin -r  /usr/local/d113/redis-cluster/70017、将/usr/local/d113/redis0-3.0.0/src目录下的redis-trib.rb文件拷贝到/usr/local/d113/redis-cluster目录,用于构建集群cp /usr/local/d113/redis-3.0.0/src/redis-trib.rb   /usr/local/d113/redis-cluster

3、构建redis集群

步骤

1-5
@@@@@@@@@@@@@构建redis集群1、将7001目录中的*.rdb,*.aof文件删除1、进入目录   cd  /usr/local/d113/redis-cluster/70012、删除   rm -rf *.rdb *.aof2、进入7001目录,修改redis.conf1、将端口改为: 70012、启用集群# cluster-enabled yes将前面的#去掉即可 cluster-enabled yes3、保存退出3、将7001复制5份,分别命名为:7002~7006  (它们就是6台redis服务器)1、进入 /usr/local/d113/cluster2、复制cp 7001 -r 7002cp 7001 -r 7003.....4、分别进入 7002~7006修改redis.conf,将端口号分别改为7002~70065、分别启动 7001~7006这些服务器1、分别进入7001~70062、分别执行 ./redis-server redis.conf
6-11
6、查看进程,看这些服务器是否启动好了 7001~7006ps -ef | grep redis7、进入/usr/local/d113/redis-cluster用 redis-trib.rb文件构建redis集群./redis-trib.rb create --replicas 1 192.168.47.128:7001 192.168.47.128:7002 192.168.47.128:7003 192.168.47.128:7004 192.168.47.128:7005 192.168.47.128:7006在执行过程中,有一个地方要求要输入,我们输入yes确定即可8、登录redis集群配置集群后,集群中的所有服务器是可以共享访问,登录其中的任意一台服务器都可以1、进入 7001目录2、通过客户端访问redis集群./redis-cli -h 192.168.47.128 -p 7001 -c9、查看集群的状态 cluster info10、查看集群中的主从机信息以及哈希槽的分配信息cluster nodes11、将7001~7006在防火墙中注册firewall-cmd --zone=public --add-port=7001/tcp --permanentfirewall-cmd --reload

4、测试集群

@@@@@@@@@@测试集群:问题1:集群中的服务器是共享的,当存储数据时,系统对键采用CRC16算法得到数值取模16384得到一个哈希值,然后就会切换该值对应哈希槽的主机7001主机:0~5460(7004)7002主机:5461~10922(7005)7003主机:10923~16384(7006)问题2:如果集群中的某一台主机如果挂了,它的从机会自动升级成主机可读可写键为stu的数据,是存放在7003这个主机中的将7003的进程关掉,7006就会升级成主机如果此时将7003启动,它将会成为7006的从机

5、Java代码访问集群

示例1:与spring无关,单独访问集群
示例1:与spring无关,单独访问集群package org.java.demo;import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;import java.util.HashSet;
import java.util.Set;/*** @author arjun* @title: clusterRedis* @description: 描述信息* @date 2023.08.20 10:15*/
//redis集群测试
public class clusterRedis {public static void main(String[] args) {/*******************连接池****************************///创建连接池的配置对象,用于设置连接池配置信息JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();//指定连接池的最小闲置连接数--------连接池最少要保证有多个闲置连接,如果没有就会马上自动创建jedisPoolConfig.setMinIdle(50);//指大最大闲置连接数jedisPoolConfig.setMaxIdle(100);//设置最大连接数jedisPoolConfig.setMaxTotal(200);//由于用完的连接并不会释放,会回到连接池,设置多余闲置连接的销毁时间jedisPoolConfig.setEvictorShutdownTimeoutMillis(3000);//设置等待连接的超时时间jedisPoolConfig.setMaxWaitMillis(3000);/******************redis集群****************************///真实项目中,不是改端口号,而是修改ip,端口号都为6379Set<HostAndPort> set=new HashSet<>();set.add(new HostAndPort("192.168.18.128",7001));set.add(new HostAndPort("192.168.18.128",7002));set.add(new HostAndPort("192.168.18.128",7003));set.add(new HostAndPort("192.168.18.128",7004));set.add(new HostAndPort("192.168.18.128",7005));set.add(new HostAndPort("192.168.18.128",7006));/*****************测试集群****************************/JedisCluster jedisCluster=new JedisCluster(set,jedisPoolConfig);String score = jedisCluster.get("id");System.out.println(score);}
}
示例2:在spring中使用集群
1、修改applicationContext-redis.xml配置集群<!--1、指定redis配置对象--><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--指定连接池的最小闲置连接数连接池最少要保证有多个闲置连接,如果没有就会马上自动创建--><property name="minIdle" value="50"/><!--最大闲置连接数--><property name="maxIdle" value="100"/><!-- 设置最大连接数--><property name="maxTotal" value="200"/><!--由于用完的连接并不会释放,会回到连接池,设置多余闲置连接的销毁时间--><property name="evictorShutdownTimeoutMillis" value="3000"/><!--设置等待连接的超时时间--><property name="maxWaitMillis" value="3000"/></bean><!--    配置redis集群--><bean id="cluster" class="redis.clients.jedis.JedisCluster"><!--指定构造参数1:redis服务器的集合--><constructor-arg index="0"><set><!--所有的redis服务器都要放在set集合--><bean class="redis.clients.jedis.HostAndPort"><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="7001"/></bean><bean class="redis.clients.jedis.HostAndPort"><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="7002"/></bean><bean class="redis.clients.jedis.HostAndPort"><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="7003"/></bean><bean class="redis.clients.jedis.HostAndPort"><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="7004"/></bean><bean class="redis.clients.jedis.HostAndPort"><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="7005"/></bean><bean class="redis.clients.jedis.HostAndPort"><constructor-arg name="host" value="192.168.47.128"/><constructor-arg name="port" value="7006"/></bean></set></constructor-arg><!--指定构造参数2:连接池的配置对象--><constructor-arg index="1" ref="jedisPoolConfig"/></bean>
2、编写JedisClient接口的实现类(采用集群的方式实现)@Component("myCluster")public class JedisClientClusterImpl implements JedisClient {@Autowiredprivate JedisCluster jedisCluster;@Overridepublic void set(String key, String value) {jedisCluster.set(key,value);}@Overridepublic String get(String key) {return jedisCluster.get(key);}@Overridepublic void hset(String key, String field, String value) {jedisCluster.hset(key,field,value);}@Overridepublic String hget(String key, String field) {return jedisCluster.hget(key,field);}@Overridepublic void hdel(String key, String filed) {jedisCluster.hdel(key,filed);}}
3、在PrdService注入JedisClient的实例 //注入jedis接口@Autowired//这种方式是按类型自动注入,它注入的接口的实现类,这种方式注入要求:只允许出现一个匹配类型(接口只有一个实现类才可以这样使用) //如果有多个匹配类型,就不能按类型注入,只能按名称注入@Qualifier("myCluster")private JedisClient jedisClient;@@@@@@@@@@Redis集群中的数据是共享访问的,但如果使用REDIS的管理工具查看集群的数据,当前主机只能看到当前主机的数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/3461.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis网络部分相关的结构体2 和 绑定回调函数细节

目录 1. struct connection ConnectionType属性 创建connection 2. struct client 3. 绑定客户端回调函数的流程 3.1. 读事件回调函数的设置 3.2. 写事件回调函数的设置 3.3. connSocketEventHandler函数 3.4. Redis5版本的设置回调函数 3.5. 个人的一些想法&#xf…

人工智能好多人都在用,那么用户画像要怎么看?

用户画像是通过对用户行为、偏好、兴趣等数据进行分析和整理&#xff0c;从而形成的关于特定用户群体的描述和模型。在人工智能应用中&#xff0c;用户画像可以起到指导个性化推荐、精准营销、产品设计等方面的作用。以下是用户画像在人工智能应用中的几个重要方面&#xff1a;…

汽车Type-C接口:特点与要求解析

汽车Type-C接口的需求增长 随着汽车科技的不断发展&#xff0c;车载电子设备的功能和数量不断增加&#xff0c;因此&#xff0c;对于汽车Type-C接口的需求也在逐渐增长。作为一种高速、多功能的连接标准&#xff0c;汽车Type-C接口在车载设备连接中扮演着越来越重要的角色。 …

Nginx 四层和七层代理区别、配置

四层&#xff1a;通过报文中的目标地址和端口&#xff0c;加上负载均衡设备设置的服务器选择方式&#xff0c;决定最终选择的内部服务器&#xff0c;使用tcp、udp协议。 七层&#xff1a;"内容交换"&#xff0c;通过报文中真正有意义的应用层内容&#xff0c;加上负…

Go开发者指南:`io/ioutil`库的实战应用全解

Go开发者指南&#xff1a;io/ioutil库的实战应用全解 概述io/ioutil函数概览ReadAllReadFileWriteFileReadDirTempFile 和 TempDir 实战技巧&#xff1a;使用io/ioutil进行文件操作高效读取文件文件的写入操作处理大文件的策略使用TempFile和TempDir管理临时文件 高级应用结合o…

【Leetcode】377. 组合总和 Ⅳ

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个由 不同 整数组成的数组 n u m s nums nums&#xff0c;和一个目标整数 t a r g e t target target 。请你从 n u m s nums nums 中找出并返回总和为 t a r g e t targ…

leetcode-二叉搜索树与双向链表-89

题目要求 思路 1.观察给的用例&#xff0c;本质上是把数据按照中序遍历连接起来 2.将结点以中序遍历的方式插入到数组中&#xff0c;注意这里是vector<TreeNode*> 3.将数组中的数据连接起来 代码实现 /* struct TreeNode {int val;struct TreeNode *left;struct TreeN…

基于昇腾AI 使用AscendCL实现垃圾分类和视频物体分类应用

现如今&#xff0c;人工智能迅猛发展&#xff0c;AI赋能产业发展的速度正在加快&#xff0c;“AI”的需求蜂拥而来&#xff0c;但AI应用快速落地的过程中仍存在很大的挑战&#xff1a;向下需要适配的硬件&#xff0c;向上需要完善的技术支持&#xff0c;两者缺一不可。 基于此&…

去雾笔记-Pixel Shuffle,逆Pixel Shuffle,棋盘效应,转置卷积

文章目录 1.Pixel Shuffle2.Inverse Pixel Shuffle3.棋盘效应4.转置卷积5.宽激活块6.PSPNet7.反射填充层&#xff08;Reflective Padding Layer&#xff09;8.tanh层 1.Pixel Shuffle Pixel Shuffle是一种用于图像超分辨率的技术&#xff0c;它通过重新排列图像的像素来增加图…

树莓派学习笔记--Wiring Pi库的安装

前言 在刚开始学习树莓派的时候&#xff0c;新版本操作系统与旧版本有一定的区别&#xff0c;就导致跟着网上的教程来出现了很多问题&#xff0c;然后网上新操作系统的教程又很少&#xff0c;就导致前些时间学习一直没有进展。最近终于是把这些问题解决了。所以记录下来这些东西…

MySql篇

索引 B-树 定义&#xff1a; 1、根节点至少包含两个孩子 2、每个节点最多包含m个孩子(m > 2)&#xff0c;m为树的深度 3、除了根节点和叶子节点&#xff0c;其他节点至少有ceil(m/2)个孩子&#xff0c;ceil函数为取上限&#xff0c;例如ceil(1.2)2&#xff0c;就是小数位…

游戏新手村18:游戏广告渠道与广告形式

上文我们说到&#xff0c;渠道为王&#xff0c;渠道可以为我们带来流量和用户&#xff0c;进而带来收入。我们可以通过哪些渠道导入用户呢&#xff1f;每个渠道有哪些优劣呢&#xff1f;在进行游戏营销推广的时候我们该如何选择呢&#xff1f; 根据付费性质&#xff0c;我们可…

Pytorch迁移学习训练病变分类模型

划分数据集 1.创建训练集文件夹和测试集文件夹 # 创建 train 文件夹 os.mkdir(os.path.join(dataset_path, train))# 创建 test 文件夹 os.mkdir(os.path.join(dataset_path, val))# 在 train 和 test 文件夹中创建各类别子文件夹 for Retinopathy in classes:os.mkdir(os.pa…

【Windows】达芬奇19安装教程

DaVinci Resolve Studio是一个结合专业的8k编辑、颜色混合、视觉效果和音频后期制作的软件。只需点击一下&#xff0c;你就可以立即在编辑、混音、特效和音频流之间切换。此外&#xff0c;达芬奇是一个多用户协作的解决方案&#xff0c;使编辑、助理、色彩学家、视觉效果设计师…

OS复习笔记ch4

引言 上一章&#xff0c;我们学习了进程的相关概念和知识&#xff0c;不知道小伙伴们的学习进度如何&#xff0c;没看的小伙伴记得去专栏看完哦。 线程从何而来 我们之前说过&#xff0c;进程是对程序运行过程的抽象&#xff0c;它的抽象程度是比较高的。 一个进程往往对应一…

C++:静态成员变量和静态成员方法

静态成员变量 C中的静态成员变量是属于类而不是类的实例的变量。这意味着无论创建了多少个类的实例&#xff0c;静态成员变量都只有一个副本&#xff0c;并且可以被所有类的实例共享。 让我们来看一个示例&#xff1a; class RolePlayer { public://静态成员变量static int …

值得让英伟达CEO黄仁勋亲自给OpenAI配送的AI服务器!一文带你了解算力,GPU,CPU!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

怎么办,孟德尔随机化连锁不平衡跑不了!这里有本地连锁不平衡分析方法

大家都知道&#xff0c;孟德尔随机化很大程度依赖于国外的服务器。 最近我们发现孟德尔随机化常用的TwoSampleMR包的clump函数经常报错&#xff0c;这是由于服务器访问人群超时造成的现象&#xff0c;当线上版本失效。 很多人做孟德尔随机化&#xff0c;就卡在clump上。 于是我…

OpenStack云计算(十)——OpenStack虚拟机实例管理,增加一个计算节点并进行实例冷迁移,增加一个计算节点的步骤,实例冷迁移的操作方法

项目实训一 本实训任务对实验环境要求较高&#xff0c;而且过程比较复杂&#xff0c;涉及的步骤非常多&#xff0c;有一定难度&#xff0c;可根据需要选做。可以考虑改为直接观看相关的微课视频 【实训题目】 增加一个计算节点并进行实例冷迁移 【实训目的】 熟悉增加一个…

牛客NC199 字符串解码【中等 递归,栈的思想 C++/Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/4e008fd863bb4681b54fb438bb859b92 相同题目&#xff1a; https://www.lintcode.com/problem/575 思路 解法和基础计算器1&#xff0c;2,3类似,递归参考答案C struct Info {string str;int stopindex;Info(str…