Redis可视化工具-安装Redis_Desktop_Manager
下载完成后连接到redis服务(redis相当于一个服务端)
注意:
1.检查防火墙是否关闭(systemctl stop firewalld.service)
查看防火墙运行情况
2.redis默认只允许本地访问,远程访问需要修改redis.conf
注释掉bind 127.0.0.1 -::1
关闭保护模式
重启redis服务(停掉后重启)
连接后双击可视化工具中的redis
(出现默认的16库)
Java整合Redis_Jedis操作
手动缓存效率低,故利用java连接工具jedis操作redis。
创建maven项目redis-demo,引入jedis包
pom文件引入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
test中创建包:
//jedis测试用例
public class JedisTest{
Jedis jedis;
//初始化jedis实例
@Before
public void init(){
//创建redis连接
jedis = new Jedis("192.168.202.100",6379);
}
//string操作
@Test
public void stringTest(){
//设置一个key
jedis.set("k1","k2");
//获取key的值
String k1 = jedis.get("k1");
System.out.println(k1);
//设置key过期时间为10
jedis.setex("k2",10,"v2");
}
//list操作
@Test
public void listTest(){
//添加元素lpush
jedis.lpush("list1","v1","v2");
jedis.rpush("list1","v3","v4");
//获取所有元素
List<String> list1 = jedis.lrange("list1",0,-1);
//遍历元素
for(String s : list1){
System.out.println(s);
}
}
//set操作
@Test
public void setTest(){
//添加元素
jedis.sadd("set1","v1","v2","v3","v3");
//获取元素
Set<String> set1 = jedis.smember("set1");
//遍历所有元素
for(String s : set1){
System.out.println(s);
}
}
//Hash操作
@Test
public void HashTest(){
//设置hash
jedis.hset("user","age","26");
jedis.hset("user","name","baizhan");
//获取所有key的value的值
List<String> user = jedis.hvals("user");
//遍历所有元素
for(String s : user){
System.out.println(s);
}
}
//zset操作
@Test
public void zsetTest(){
//添加元素
jedis.zadd("zset",100,"Java");
jedis.zadd("zset",200,"Python");
jedis.zadd("zset",300,"C++");
jedis.zadd("zset",400,"C");
//获取所有值
Set<String> zset = jedis.zrange("zset",0,-1);
//遍历所有值
for(String s : zset){
System.out.println(s);
}
}
//bitmaps数据类型
@Test
public void bitmapTest(){
//给张三添加上班打卡记录
jedis.setbit("zhangsan:2",0,"1");//第一天
jedis.setbit("zhangsan:2",1,"1");
jedis.setbit("zhangsan:2",2,"0");//第三天
jedis.setbit("zhangsan:2",3,"1");
//获取张三第3天的上班记录(是否迟到)
Boolean getbit = jedis.getbit("zhangsan:2",2);
//如果是1为true 0为false
System.out.println(getbit);
}
//geo操作
@Test
public void geoTest(){
//添加地理信息
jedis.geoadd("china",130,30,"beijing");
//获取地理信息
List<GeoCoordinate> geopos = jedis.geopos("china","beijing");
//遍历位置信息
for(GeoCoordinate geopo : geopos){
System.out.println(geopo.toString());
}
}
//hyperLog操作
@Test
public void hyperLogTest(){
//添加元素
jedis.pfadd("book","uid1","uid2","uid3","uid2","uid2");
//获取书籍数量
long bookCount = jedis.pfcount("book");
System.out.println(bookCount);
}
//关闭jedis实例
@After
public void close(){
//关闭redis连接
jedis.close();
}
}
Java整合Redis_Spring-Data-Reids
简介
Spring-Data-Redis是spring大家族的一部分,通过简单的配置访问Redis服务,对Reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了Redis各种操作、异常处理及序列化,支持发布订阅。
RedisTemplate介绍
Spring封装了RedisTemplate对象来进行对Redis的各种操作,它支持所有的Redis原生的api。
注意:
- K:模板中的Redis key的类型,模板中的Redis key的类型(通常为String)如:RedisTemplate<String, Object>。
- V:模板中的Redis value的类型
RedisTemplate中定义了对5种数据结构操作
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
创建一个SpringBoot项目
1.配置文件(告诉其我们的redis服务在哪里)
#Redis服务器连接地址
spring.redis.host=192.168.202.100
#Redis服务器连接端口
spring.redis.port=6379
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000
2.通过测试类启动redis并操作redis服务
StringRedisTemplate与RedisTemplate
两者的关系是StringRedisTemplate继承RedisTemplate。
两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
修改String的序列化机制为json序列化
3.在测试类前创建config包修改序列话方式(json)
/**
* 自定义序列化方式
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
//创建一个redis
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//添加序列化机制key,value,hashkey
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
//添加到工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
重新在测试类中运行
获取数据
4.通过该方式操作列表list
添加元素
弹出数据
5.针对hash操作
添加元素
获取元素
public Object hget(String key,String field){
return redisTemplate.opsForHash().get(key,field);
}
6.set操作:添加与获取
获取set集合的长度
7.zset操作:添加与获取
@Test
public void zsetTest(){
//添加元素
redisTemplate.opsForZset().add("z1","z1",67);
redisTemplate.opsForZset().add("z1","z2",68);
redisTemplate.opsForZset().add("z1","z3",69);
//获取元素
redisTemplate.opsForZset().rangeByScore("z1",50,69);
for(Object o : z1){
System.out.println(o.toString());
}
}
Redis构建web应用实践_网页缓存
创建SpringBoot项目
1.修改版本![](https://i-blog.csdnimg.cn/blog_migrate/724f0bc6e98a3a6e78ea947c5a5506ee.png)
2.配置文件
########################################################
### 配置连接池数据库访问配置
########################################################
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.202.100:3306/zhonglian?characterEncoding=utf-8&&useSSL=false
spring.datasource.username=root
spring.datasource.password=5428
### Java Persistence Api --y
########################################################
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
#[org.hibernate.cfg.ImprovedNamingStrategy #org.hibernate.cfg.DefaultNamingStrategy]
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
########################################################
### 配置连接池数据库访问配置
########################################################
#Redis服务器连接地址
spring.redis.host=192.168.202.100
#Redis服务器连接端口
spring.redis.port=6379
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000
logging.pattern.console=%d{MM/dd HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n
3.打一个日志@SLf4j在文件中进行测试
查看项目是否启动成功
4.创建商品数据模型
@Data
@Entity
@Table(name = "goods")
public class GoodsEntity {
//自增ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)//自增
private Long id;
// 商品名字
private String goodsName;
// 订单id
private String orderId;
// 商品数量
private Integer goodsNum;
// 商品价格
private Double price;
}
5.商品业务层
@Repository
@Service
public class GoodsService {
//商品
@Autowired
private GoodsRepository goodsRepository;
/**
* 根据id获取商品信息
* @param 商品id
* @return
*/
public GoodsEntity getById(Long id){
//从数据库中根据id查询商品信息
Optional<GoodsEntity> optionGoodsEntity = goodsRepository.findById(id);
if (optionGoodsEntity.isPresent()){
return optionGoodsEntity.get();
}else {
return null;
}
}
}
6.编写控制层
/**
* 商品控制层
*/
@RequestMapping("/goods")
@RestController
public class GoodsController {
//商品业务层
@Autowired
private GoodsService goodsService;
/**
* 根据id查询商品信息
* 10000并发 1414qps
* @param id
* @return
*/
@GetMapping("/getById")
public GoodsEntity getById(@PathVariable String id){
return goodsService.getId(Long.valueOf(id));
}
}
7.启动项目进行测试
8.数据库中成功出现创建的表后添加数据![](https://i-blog.csdnimg.cn/blog_migrate/fc9fca8c0c431be3b53e75ca90771305.png)
9.打开浏览器进行测试(此时无缓存)
10.打开测压工具
添加线程组
添加http请求
添加聚合报告(查看没有缓存时的吞吐量)
11.业务层中添加缓存
查询缓存,判断缓存
添加依赖
@Repository
@Service
public class GoodsService {
//商品
@Autowired
private GoodsRepository goodsRepository;
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 根据id获取商品信息
* @param id
* @return
*/
public GoodsEntity getById(Long id){
// 从Redis中获取缓存
String goodsString = stringRedisTemplate.opsForValue().get("goods:id:"+ id);
// 判断是否有缓存
if (StringUtils.isEmpty(goodsString)){
//根据id查询商品信息
Optional<GoodsEntity> optionalGoodsEntity = goodsRepository.getById(id);
if(optionalGoodsEntity.isPresent()){
GoodsEntity goosEntity = optionalGoodsEntity.get();
//把对象转json字符串 {"id":1,"goodsName":"sdf"}
String goodsEntityJson = JSON.toJSONString(goodsEntity);
//添加缓存
stringRedisTemplate.opsForValue().set("goods:"+id,goodsEntityJson);
}
return goodsEntity;
}else {
// 把json数据转为goods对象
return JSON.parseObject(goodsString,GoodsEntity.class);
}
return null;
}
}
12.在浏览器器中再次请求![](https://i-blog.csdnimg.cn/blog_migrate/5f9cd50d7fe040e95e0cf48bed6c4d9a.png)
再次查看缓存后的吞吐量
Redis配置文件
units单位
配置大小单位,开头定义基本度量单位,只支持bytes,大小写不敏感。
INCLUDES
Redis只有一个配置文件,如果多个人进行开发维护,那么就需要多个这样的配置文件,这时候多个配置文件就可以在此通过 include /path/to/local.conf 配置进来,而原本的 redis.conf 配置文件就作为一个总闸。
NETWORK(网卡)
参数:
- bind:绑定redis服务器网卡IP,如果bind为空表示任何ip都可以访问,默认为127.0.0.1,即本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接。如果bind选项为空的话,那会接受所有来自于可用网络接口的连接。
- port:指定redis运行的端口,默认是6379。由于Redis是单线程模型,因此单机开多个Redis进程的时候会修改端口。
- timeout:设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接。默认值为0,表示不关闭。
- tcp-keepalive :单位是秒,表示将周期性的使用SO_KEEPALIVE检测客户端是否还处于健康状态,避免服务器一直阻塞,官方给出的建议值是300s,如果设置为0,则不会周期性的检测。
GENERAL
具体配置详解:
- daemonize:设置为yes表示指定Redis以守护进程的方式启动(后台启动)。默认值为 no
- pidfile:配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面
- loglevel :定义日志级别。默认值为notice,有如下4种取值:
debug(记录大量日志信息,适用于开发、测试阶段)
verbose(较多日志信息)
notice(适量日志信息,使用于生产环境)
warning(仅有部分重要、关键信息才会被记录)
- logfile :配置log文件地址,默认打印在命令行终端的窗口上
- databases:设置数据库的数目。默认的数据库是DB 0 ,可以在每个连接上使用select 命令选择一个不同的数据库,dbid是一个介于0到databases - 1 之间的数值。默认值是 16,也就是说默认Redis有16个数据库。
SNAPSHOTTING
这里的配置主要用来做持久化操作。
参数:
save:这里是用来配置触发 Redis的持久化条件,也就是什么时候将内存中的数据保存到硬盘
save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存 save 300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存 save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存
REPLICATION
参数:
- slave-serve-stale-data:默认值为yes。当一个 slave 与 master 失去联系,或者复制正在进行的时候,
slave 可能会有两种表现:
如果为 yes ,slave 仍然会应答客户端请求,但返回的数据可能是过时,或者数据可能是空的在第一次同步的时候
- 如果为 no ,在你执行除了 info he salveof 之外的其他命令时,slave 都将返回一个 "SYNC with master in progress" 的错误
- slave-read-only:配置Redis的Slave实例是否接受写操作,即Slave是否为只读Redis。默认值为yes。
- repl-diskless-sync:主从数据复制是否使用无硬盘复制功能。默认值为no。
- repl-diskless-sync-delay:当启用无硬盘备份,服务器等待一段时间后才会通过套接字向从站传送RDB文件,这个等待时间是可配置的。
- repl-disable-tcp-nodelay:同步之后是否禁用从站上的TCP_NODELAY 如果你选择yes,redis会使用较少量的TCP包和带宽向从站发送数据。
SECURITY
requirepass:设置redis连接密码。
比如: requirepass 123 表示redis的连接密码为123。
CLIENTS
参数:
maxclients :设置客户端最大并发连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件。 描述符数-32(redis server自身会使用一些),如果设置 maxclients为0 。表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
MEMORY MANAGEMENT
参数:
- maxmemory:设置Redis的最大内存,如果设置为0 。表示不作限制。通常是配合下面介绍的maxmemory-policy参数一起使用。
- maxmemory-policy :当内存使用达到maxmemory设置的最大值时,redis使用的内存清除策略。有以下几种可以选择:
1)volatile-lru 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )
2)allkeys-lru 利用LRU算法移除任何key
3)volatile-random 移除设置过过期时间的随机key
4)allkeys-random 移除随机ke
5)volatile-ttl 移除即将过期的key(minor TTL)
6)noeviction noeviction 不移除任何key,只是返回一个写错误 ,默认选项
- maxmemory-samples :LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存)。随意你可以选择样本大小进行检,redis默认选择3个样本进行检测,你可以通过maxmemory-samples进行设置样本数。
APPEND ONLY MODE
参数:
- appendonly:默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式, 可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入appendonly.aof文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认值为no。
- appendfilename :aof文件名,默认是"appendonly.aof"
- appendfsync:aof持久化策略的配置;no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快;always表示每次写入都执行fsync,以保证数据同步到磁盘;everysec表示每秒执行一次fsync,可能会导致丢失这1s数据
LUA SCRIPTING
参数:
lua-time-limit:一个lua脚本执行的最大时间,单位为ms。默认值为5000.
REDIS CLUSTER
参数:
- cluster-enabled:集群开关,默认是不开启集群模式。
- cluster-config-file:集群配置文件的名称。
- cluster-node-timeout :可以配置值为15000。节点互连超时的阀值,集群节点超时毫秒数
- cluster-slave-validity-factor :可以配置值为10。
redis其他功能-发布订阅
发送者发送消息,订阅者订阅消息。
Redis的发布与订阅
1.进入redis服务中创建一个订阅
2.第二个终端中再次订阅(当做客户端即消息的发送者)
3.第三个终端(相当于发布者)
4.打开第一个和第二个终端收到第三个终端发布的hello消息
Redis其他功能_慢查询
Redis命令执行的整个过程
两点说明:
- 慢查询发生在第3阶段
- 客户端超时不一定慢查询,但慢查询是客户端超时的一个可能因素
- 慢查询日志是存放在Redis内存列表中。
获取慢查询日志
参数:
- 唯一标识ID
- 命令执行的时间戳
- 命令执行时长
- 执行的命名和参数
获取慢查询日志的长度
可以使用slowlog len
命令获取慢查询日志的长度。
注意:
当前Redis中有121条慢查询日志。
配置慢查询的参数
- 命令执行时长的指定阈值 slowlog-log-slower-than。
slowlog-log-slower-than的作用是指定命令执行时长的阈值,执行命令的时长超过这个阈值时就会被记录下来。
- 存放慢查询日志的条数 slowlog-max-len。
slowlog-max-len的作用是指定慢查询日志最多存储的条数。实际上,Redis使用了一个列表存放慢查询日志,slowlog-max-len就是这个列表的最大长度。
查看慢日志配置
查看redis慢日志配置,登陆redis服务器,使用redis-cli客户端连接redis server
修改Redis配置文件
比如,把slowlog-log-slower-than设置为1000,slowlog-max-len设置为1200:
重启
使用config set
命令动态修改
比如,还是把slowlog-log-slower-than设置为1000,slowlog-max-len设置为1200:
实践建议
slowlog-max-len配置建议
- 线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。
- 增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000以上。
slowlog-log-slower-than配置建议
- 默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。
- 由于Redis采用单线程响应命令,对于高流量的场景,如果命令执行时间在1毫秒以上,那么Redis最多可支撑OPS不到1000。因此对于高OPS场景的Redis建议设置为1毫秒。
慢查询主要作用:定位系统中存在的慢操作
Redis其他功能_流水线pipeline
1次网络命令通信模型
经历了1次时间 = 1次网络时间 + 1次命令时间。
批量网络命令通信模型
经历了 n次时间 = n次网络时间 + n次命令时间
流水线
经历了 1次pipeline(n条命令) = 1次网络时间 + n次命令时间,这大大减少了网络时间的开销,这就是流水线。
注意:
在执行批量操作而没有使用pipeline功能,会将大量的时间耗费在每一次网络传输的过程上;而使用pipeline后,只需要经过一次网络传输,然后批量在redis端进行命令操作。这会大大提高了效率。
pipeline-Jedis实现
没有pipeline的测试
有pipeline的测试
查看测试结果的用时时间
pipeline主要作用:减少了网络时间的开销
Redis数据安全_持久化机制概述
内存的数据持久化的磁盘上,reids重启后可以从磁盘中恢复数据
持久化机制概述
对于Redis而言,持久化机制是指把内存中的数据存为硬盘文件, 这样当Redis重启或服务器故障时能根据持久化后的硬盘文件恢复数 据。
Redis数据安全_RDB持久化机制
rdb实在一定时间内将内存数据以快照写入磁盘。(此时文件为经过压缩的二进制文件)
Redis数据安全_AOF持久化机制实战
rdb可能丢失数据
AOF是什么
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来。
AOF默认不开启
可以在redis.conf中配置文件名称,默认为appendonly.aof。
重启服务
可以查看到appendonly.aof文件(以写命令的方式创建)
aof可以恢复数据
进入appendonly.aof文件删除flushall:
再次运行时redis会重新执行一次aof文件恢复数据
AOF同步频率设置
参数:
- appendfsync always
始终同步,每次Redis的写入都会立刻记入日志,性能较差但数据完整性比较好。
- appendfsync everysec
每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
- appendfsync no
redis不主动进行同步,把同步时机交给操作系统。
优势
- 备份机制更稳健,丢失数据概率更低。
- 可读的日志文本,通过操作AOF稳健,可以处理误操作。
劣势
- 比起RDB占用更多的磁盘空间。
- 恢复备份速度要慢。
- 每次读写都同步的话,有一定的性能压力。
reids中aof持久化主要解决数据丢失问题
Redis数据安全_如何选用持久化方式
利用文件修复数据
综合使用AOF和RDB两种持久化机制
用AOF来保证数据不丢失,作为数据恢复的第一选择,用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。