文章目录
前置知识
jvm内置缓存
Oscache,Ehcache,Jcache,Jbosscache
jvm内置缓存和nosql缓存一样,存在内存中
mybatis和hibernate二级缓存是oscache,ehcache jvm内置缓存
OsCache与EhCache区别
ehcache 主要是对数据库访问的缓存,相同的查询语句只需查询一次数据库,从而提高了查询的速度,使用spring的AOP可以很容易实现这一功能。(Springboot支持)
oscache 主要是对页面的缓存,可以整页或者指定网页某一部分缓存,同时指定他的过期时间,这样在此时间段里面访问的数据都是一样的。
缺点
- 容易内存溢出
- 没有持久化机制
- 不能分布式(不能共享)
memcache
Redis与memcached相比有哪些优势?
1.memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
2.redis的速度比memcached快很多
3.redis可以持久化其数据
开源、高性能、分布式的内存对象缓存系统,用于动态web应用以减轻数据库的负载。
- Memcache作为一个缓存区域,将数据和对象存在内存中来减少读取数据库的次数,提高网站访问速度
- Memcache是一个存储键值对的HashMap
- 进行分布式,毕竟单台memcache的内存容量是有限的
redis 更优,memcache仅适合缓存
memcache没有持久化功能,服务器关闭则数据消失
非阻塞式,可以接受很多线程
工作原理
在内存中开辟一个空间,然后建立一个HashTable,Memcache管理这个hash表
结构
- 服务器端 11211
- 客户端
一、基础
简介 开源
- key-value存储系统。
- 开源的使用ANSI C语言编写(需要安装gcc-c++)、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
- 常用类型,值(value):字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
- redis的单线程的
什么是 BSD 协议?
BSD介绍
Redis 优势
● 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
● 丰富的数据类型
● 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
● 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
● 高可用
Redis与其他key-value存储有什么不同?
● Redis有着更为复杂的数据结构并且提供对他们的原子性操作。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
● Redis运行在内存中但是周期性把数据持久化到磁盘(RDB),或者把修改操作追加到文件记(AOF)。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
redis如何关闭持久化
应用场景:
[涉及高并发或者是存在大量读数据的情况下]
缓存 - 任务队列
应用排行榜,网站访问统计,数据过期处理,分布式集群架构中的session分离
redis保存用户的购物车信息、生成订单号、访问量计数器、分布式锁,验证码,session共享
额外的探索
- redis的key和string类型value限制均为512MB。
- 默认16个库
为什么这么快?
完全基于内存
数据结构简单,对数据操作也简单
采用单线程,避免了不必要的上下文切换和竞争条件
使用多路I/O复用模型,非阻塞IO
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。
二、安装与分布式安装
安装教程-菜鸟教程网站
yum -y install gcc
yum install gcc-c++
安装失败合集
./redis-cli -h 127.0.0.1 -p 6379
>set key value
>get key
>ping
pong
Redis 配置文件
Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf。
主要配置修改密码:requirepass 123456
配置连接我的有道笔记:点这里
让其他电脑访问到redis三种设置
1.关闭绑定本机
2.redis.conf中设置保护模式为no
3.设置密码
主从部署文章请参考我的其他博客点击链接
三、分布式锁
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
/**
* 简易Redis分布式锁
* <p>
* 根据redis单线程(原子性)特性,防止多点定时任务执行重复
* 此工具类需要引用spring-redis至少2.1版本
* <dependency>
* <groupId>org.springframework.data</groupId>
* <artifactId>spring-data-redis</artifactId>
* <version>2.1.2.RELEASE</version>
* </dependency>
*
* 测试使用示例:
* @Test
* public void test() {
* String lockValue = UUID.randomUUID().toString();
* String lockKey = "key";
* try {
* // 问题所在 ,等待多长时间????
* if (RedisLockUtils.lock(redisTemplate, lockKey, lockValue, 10, TimeUnit.SECONDS)) {
* // 业务逻辑
* System.out.println("业务逻辑");
* } else {
* System.out.println("对象被上锁,请稍后再试");
* }
* } finally {
* if (lockValue.equals(RedisLockUtils.getLock(redisTemplate, lockKey))) {
* System.out.println("高并发场景下,只有锁对象和加锁对象是同一个线程,才能释放锁");
* RedisLockUtils.delLock(redisTemplate, lockKey);
* }
* }
* }
*
* @author zhaojy
* @date 2019/11/14
*/
public class RedisLockUtils {
/**
* 上锁
* <p>
* 使用redis的setNx命令:不存在时设置值,存在不做任何动作
* 同时设置了锁超时时间防止死锁
*
* @param redisTemplate redis模板
* @param key key值
* @param value value:锁对象
* @param time 有效时间(数值)
* @param timeUnit 有效时间(单位)TimeUnit.MINUTES
* @return 成功返回true, 失败false
*/
public static Boolean lock(RedisTemplate<String, Object> redisTemplate, String key, String value, int time, TimeUnit timeUnit) {
return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
}
/**
* 释放锁
* <p>
* [强制]使用try-finally强制拆锁,防止死锁
*
* @param redisTemplate redis模板
* @param key key值
*/
public static void delLock(RedisTemplate<String, Object> redisTemplate, String key) {
redisTemplate.delete(key);
}
/**
* 获取锁
*
* 并发场景下,释放锁需要判断
*
* @param redisTemplate 模板
* @param key key
* @return 返回 [锁对象]
*/
public static Object getLock(RedisTemplate<String, Object> redisTemplate, String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 获取锁剩余生存时间
*
* @param redisTemplate
* @param key
* @return
*/
public static long getLockTime(RedisTemplate<String, Object> redisTemplate, String key) {
return redisTemplate.getExpire(key);
}
}
四、整合进springboot/做缓存
1.Jedis操作数据库
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
java代码
Jedis jedis = new Jedis("192.168.18.2",6379);
//设置密码时必须验证密码
jedis.auth("123456");
//----------string
jedis.set("name","zhaojianyu");
jedis.get();
//----------hash
Map map = new HashMap