SSM使用redis开发流程,你真的熟悉吗?(包括redis安装启动,数据类型,持久化,集群)

9 篇文章 0 订阅
4 篇文章 0 订阅

站在一级台阶上
自以为窥见了天光。

1,什么是redis

Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

2,使用redis的优点

性能极高 – Redis能支持超过 100K+ 每秒的读写频率。
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

3,使用redis的缺点

是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

总结: Redis受限于特定的场景,专注于特定的领域之下,速度相当之快,目前还未找到能替代使用产品。

4,redis的安装

Redis是c语言开发的。
安装redis需要c语言的编译环境。如果没有gcc需要在线安装。yum install gcc-c++

安装步骤:
第一步:redis的源码包上传到linux系统。
第二步:解压缩redis。
第三步:编译。进入redis源码目录。make
第四步:安装。make install PREFIX=/usr/local/redis
PREFIX参数指定redis的安装目录。一般软件安装到/usr目录下

5,redis的连接

5.1,redis的启动

前端启动:在redis的安装目录下直接启动redis-server.

[root@localhost bin]# ./redis-server 

后台启动:
把/root/redis-3.0.0/redis.conf复制到/usr/local/redis/bin目录下

[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis/bin/

后台启动的话,需要修改配置文件,打开安装的redis的文件目录,打开里面的redis.conf的配置文件,把配置文件的daemonize no改成daemonize yes,使用vim命令进行修改,使用“/内容”进行查找。

启动

[root@localhost bin]# ./redis-server redis.conf

判断是否启动可查看系统进程

[root@localhost bin]# ps aux|grep redis

启动成功

5.2,Redis-cli

命令行使用

[root@localhost bin]# ./redis-cli 

默认连接localhost运行在6379端口的redis服务

[root@localhost bin]# ./redis-cli -h 192.168.25.153 -p 6379

-h:连接的服务器的地址
-p:服务的端口号

关闭redis

[root@localhost bin]# ./redis-cli shutdown

5.3,Redis的五种数据类型

主要介绍常用的String和hash,有时间会出命令大全
keys * 查询所有键

5.3.1,String类型

String:key-value(做缓存)
Redis中所有的数据都是字符串。命令不区分大小写,key是区分大小写的。Redis是单线程的。Redis中不适合保存内容大的数据。

存取数据,set和get方法

127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> get name
"zhangsan"

自增自减,incr和decr,没有则自动创建

127.0.0.1:6379> incr ago
(integer) 1
127.0.0.1:6379> get ago
"1"
5.3.2,Hash类型(做缓存)

相当于一个key对于一个map,map中还有key-value
使用hash对key进行归类。
Hset:向hash中添加内容
Hget:从hash中取内容

127.0.0.1:6379> hset key name zhangsan
(integer) 1
127.0.0.1:6379> hget key name
"zhangsan"
5.3.3,List类型

有顺序可重复

5.3.4,Set类型

无序不重复

5.3.5,SortedSet类型

有序不重复

5.4,Key命令

expire key second:设置key的过期时间
ttl key:查看key的有效期(-1代表持久化,-2代表已过期)
persist key:清除key的过期时间。Key持久化

127.0.0.1:6379> expire a 50
(integer) 1
127.0.0.1:6379> ttl a
(integer) 34
127.0.0.1:6379> persist a
(integer) 1
127.0.0.1:6379> ttl a
(integer) -1

6,Redis的持久化方案

Redis的所有数据都是保存到内存中的。

:Rdb

Rdb:(默认方案)快照形式,定期把内存中当前时刻的数据保存到磁盘。Redis默认支持的持久化方案,存在丢失数据的风险。
—在redis.conf配置文件中配置

save 900 1
save 300 10
save 60 a0000

900秒内执行1次的话会在900秒的时候持久化数据…

:AOF

aof形式:append only file。把所有对redis数据库操作的命令,增删改操作的命令。保存到文件中。数据库恢复时把所有的命令执行一遍即可,会降低redis的性能。
—在redis.conf配置文件中配置

appendonly  yes

7,Redis集群的搭建

7.1,redis-cluster架构图

在这里插入图片描述
redis-cluster投票:容错,有超过一半的认为其中一个出问题了,那真个redis就集体罢工了
在这里插入图片描述
架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

如何让n太服务器共同承担文件存储任务,而不是由一个服务器工作?

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点

7.,2,Redis集群的搭建

Redis集群中至少应该有三个节点。要保证集群的高可用,需要每个节点有一个备份机。
Redis集群至少需要6台服务器。
搭建伪分布式。可以使用一台虚拟机运行6个redis实例。需要修改redis的端口号7001-7006

7.2.1,集群搭建环境

1、使用ruby脚本搭建集群。需要ruby的运行环境。
安装ruby
yum install ruby
yum install rubygems

2、安装ruby脚本运行使用的包。

[root@localhost ~]# gem install redis-3.0.0.gem 
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0...
Installing RDoc documentation for redis-3.0.0...

3.编译rb脚本文件

查询后缀名为rb的文件
[root@localhost ~]# cd redis-3.0.0/src
[root@localhost src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 4月   1 2015 redis-trib.rb
把脚本拷贝到6个redis的文件夹中
[root@Jeck1 src]# cp redis-trib.rb /usr/local/redis-cluster

rb脚本运行还需要第三方库,redis3.0.0.gem

[root@Jeck1 local]# gem install redis-3.0.0

7.2.2,搭建步骤(关闭防火墙)

需要6台redis服务器。搭建伪分布式。
需要6个redis实例。
需要运行在不同的端口7001-7006

第一步:创建6个redis实例,每个实例运行在不同的端口。需要修改redis.conf配置文件。配置文件中还需要把cluster-enabled yes前的注释去掉。
在这里插入图片描述
第二步:启动每个redis实例。
设置启动脚本文件start-all.sh

在这里插入图片描述
第三步:使用ruby脚本搭建集群

[root@Jeck1 redis-cluster]# ./redis-trib.rb create --replicas 1 
192.168.240.129:7001 
192.168.240.129:7002 
192.168.240.129:7003 
192.168.240.129:7004 
192.168.240.129:7005 
192.168.240.129:7006

系统说把7001-7003作为主数据库
在这里插入图片描述
把7004-7006作为备用数据库,其中7001和7003相对应其他类似
在这里插入图片描述
每个数据库分配的哈希槽也告诉了
在这里插入图片描述

7.2.3,集群的使用方法

Redis-cli连接集群

[root@localhost redis-cluster]# redis01/redis-cli -p 7002 -c
-c:代表连接的是redis集群

8,Jedis

需要把jedis依赖的jar包添加到工程中。Maven工程中需要把jedis的坐标添加到依赖。推荐添加到服务层。

8.1,连接单机版

第一步:创建一个Jedis对象。需要指定服务端的ip及端口。
第二步:使用Jedis对象操作数据库,每个redis命令对应一个方法。
第三步:打印结果。
第四步:关闭Jedis

	@Test
	public void jedisTest() {
//		创建jedis对象
		Jedis jedis = new Jedis("192.168.240.129", 6379);
		//使用jedis对象执行操作
		jedis.set("name", "张三");
		jedis.set("name", "lisi");
		String string = jedis.get("name");
		System.out.println(string);
		//关闭连接
		jedis.close();
	}

8.2,连接单机版使用连接池

第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。
第二步:从JedisPool中获得Jedis对象。
第三步:使用Jedis操作redis服务器。
第四步:操作完毕后关闭jedis对象,连接池回收资源。
第五步:关闭JedisPool对象。

	@Test
	public void jedisPoolTest() {
		//创建连接池对象
		JedisPool jedisPool=new JedisPool("192.168.240.129",6379);
		//获取jedis
		Jedis jedis = jedisPool.getResource();
		//执行操作
		String string = jedis.get("name");
		System.out.println(string);
		//关闭连接,连接池回收资源
		jedis.close();
		//关闭连接池
		jedisPool.close();
	}

8.3,连接集群版

第一步:使用JedisCluster对象。需要一个Set参数。Redis节点的列表。
第二步:直接使用JedisCluster对象操作redis。在系统中单例存在。
第三步:打印结果
第四步:系统关闭前,关闭JedisCluster对象。

	@Test
	public void jedisClusterTest() {//集群使用
		//创建一个JedisCluster对象,有一个参数nodes是一个set类型,set中包含着若干个HostAndPort对象
		Set<HostAndPort> nodes=new HashSet<>();
		nodes.add(new HostAndPort("192.168.240.129",7001));
		nodes.add(new HostAndPort("192.168.240.129",7002));
		nodes.add(new HostAndPort("192.168.240.129",7003));
		nodes.add(new HostAndPort("192.168.240.129",7004));
		nodes.add(new HostAndPort("192.168.240.129",7005));
		nodes.add(new HostAndPort("192.168.240.129",7006));
		JedisCluster jedisCluster=new JedisCluster(nodes);
		//直接使用JedisCluster对象操作redis
		jedisCluster.set("name", "zhangsan");
		jedisCluster.set("ago", "12");
		String string = jedisCluster.get("name");
		System.err.println(string);
		String string2 = jedisCluster.get("ago");
		System.err.println(string2);
		//关闭JidesCluster对象
		jedisCluster.close();
	}

9,向业务逻辑中添加缓存

9.1,接口封装

常用的操作redis的方法提取出一个接口,分别对应单机版和集群版创建两个实现类

9.2 配置applicationContext-redis.xml

9.2.1,配置单机版
	<bean id="jedisClientPool" class="cn.e3mall.common.jedis.JedisClientPool">
		<property name="jedisPool" ref="jedisPool"></property>
	</bean>	
	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
		<!-- 构造方法参数使用constructor-arg -->
		<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
		<constructor-arg name="port" value="6379"></constructor-arg>
	</bean>
9.2.2,配置集群版
<bean id="jedisClientCluster" class="cn.e3mall.common.jedis.JedisClientCluster">
		<property name="jedisCluster" ref="jedisCluster"></property>
	</bean>
	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
		<constructor-arg name="nodes">
			<set>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
					<constructor-arg name="port" value="7001"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
					<constructor-arg name="port" value="7002"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
					<constructor-arg name="port" value="7003"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
					<constructor-arg name="port" value="7004"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
					<constructor-arg name="port" value="7005"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.240.129"></constructor-arg>
					<constructor-arg name="port" value="7006"></constructor-arg>
				</bean>
			</set>
		</constructor-arg>
	</bean>

9.3,书写Test进行操作实现

单机版和集群版2选1,实现接口的好处,在开发阶段可实现单机版进行开发,在正式上线的时候可修改配置文件,实现集群版

	@Test
	public void demo1() {
		//初始化spring容器
		ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
		//从spring容器中拿出jedisClient对象
		JedisClient jedis = (JedisClient) ac.getBean(JedisClient.class);//单机版和集群版都是JedisClient的实现类
		//惊醒操作
		jedis.set("name","zhangsan");
		String string = jedis.get("name");
		System.out.println(string);
	}

9.4,给项目中正式添加redis

9.4.1,给service添加变量
	@Autowired
	private JedisClient jedisClient;
9.4.2,具体实现
		//查询缓存
		try {
			String hget = jedisClient.hget(content_list, categoryId+"");
			if(!StringUtils.isEmpty(hget)) {
				List<TbContent> selectByExample = JsonUtils.jsonToList(hget, TbContent.class);
				
				EasyUIDataResult result=new EasyUIDataResult();
				result.setRows(selectByExample);
				//取分页结果
				PageInfo<TbContent> pageInfo=new PageInfo<TbContent>(selectByExample);
				long total = pageInfo.getTotal();
				result.setTotal(total);
				return result;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		//redis查询不到就查询数据库,并把结果添加到缓存
		try {
			jedisClient.hset("content_list", categoryId+"", JsonUtils.objectToJson(selectByExample));
		} catch (Exception e) {
			e.printStackTrace();
		}
9.4.3,缓存同步

给查询列表添加redis后,如果进行修改删除更新操作,而redis中数据没有改变,这时候就需要缓存同步到redis,已便修改删除更新操作之后再redis中保存的是最新的数据。
思路是在修改更新删除操作后删除redis存储的数据,重新从数据库中查到最新数据保存到redis中。

		//缓存同步, 删除缓存中对应的数据
		jedisClient.hdel(content_list, content.getCategoryId().toString());

文章持续更新,可以微信搜索「 绅堂Style 」第一时间阅读,回复【资料】有我准备的面试题笔记。
GitHub https://github.com/dtt11111/Nodes 有总结面试完整考点、资料以及我的系列文章。欢迎Star。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值