一。下载安装
windows: https://github.com/microsoftarchive/redis/releases
Linux:见官网
可视化工具Redis Desktop Manager:https://github.com/uglide/RedisDesktopManager/releases/tag/0.9.3
二。启动服务端与关闭服务端
启动服务端
windows:
打开一个 cmd 窗口,进入D盘目录: `cd D:\Redis Windows x64\Redis-x64-3.0.504`
运行启动命令 `redis-server.exe redis.windows.conf`
linux:先make编译src文件夹里面出现redis-server,然后cd src目录,命令: src/redis-server redis.conf
这时候redis服务就启动了,可以用桌面客户端连接。如果桌面客户端无法连接如下操作:
1.修改redis.conf配置文件中的bind改为0.0.0.0或者注释掉
2.设置为非保护模式 protected-mode设置为no(默认yes)
3.阿里云轻量应用服务器防火墙添加6379协议端口
4.配置文件启动redis src/redis-server redis.conf
验证redis是否启动成功:
方法1:redis连接工具连接
方法2(linux): ps -ef | grep redis
关闭服务端:
windows:
直接关闭CMD窗口
linux:
src/redis-cli shutdown
三。客户端登录
另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端 也要切换到 redis 目录下运行
windows
redis-cli.exe -h 127.0.0.1 -p 6379 //登录
redis-cli -h 127.0.0.1 -p 6379 shutdown //退出登录
linux
src/redis-cli -h 127.0.0.1 -p 6379 //客户端登录
ctrl + c //客户端退出登录
四.客户端登录的命令
redis-cli.exe -h 127.0.0.1 -p 6379 //登录
redis-cli -h 127.0.0.1 -p 6379 shutdown //退出登录
kill -9 //粗暴杀死redis进程
set myKey abc //设置值 (区分大小写)
get myKey //取值(区分大小写)
keys * //查看所有key
keys *e* //查看所有匹配的key
Redis NOAUTH Authentication required的解决办法:
没有权限,输入 auth 密码 即可
五。Redis持久化的两种机制 RDB 和 AOF
RDB持久化配置:安装目录下的 redis.windows.conf 文件
save 900 1
save 300 10 //每隔300s有10个key发生变化就生成一个新的快照
save 60 10000
六 java代码连接redis
单节点架构或者主从架构
1、Jedis方式连接单节点架构
1.pom引入jedis依赖包
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
2.使用
@GetMapping("/jedis")
public void testJedis() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
//连接池
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.61.148", 6379, 3000, null);
Jedis jedis = null;
try {
//从redis连接池里拿出一个jedis
jedis = jedisPool.getResource();
//1.五种数据结构基本操作,客户端api怎么用,这边就怎么用
//string
System.out.println(jedis.set("single", "zhuge"));
System.out.println(jedis.get("single"));
//hash
Map map = new HashMap();
map.put("name", "zhangsan");
map.put("age", "5");
System.out.println(jedis.hmset("hashkey2", map));
System.out.println(jedis.hgetAll("hashkey2"));
//2.管道操作实例(多条命令一次性发送进行执行 管道不具有原子性)
Pipeline pipelined = jedis.pipelined();
for (int i = 1; i <= 10; i++) {
pipelined.set("zhuge" + i, "zhuge");
}
List<Object> result = pipelined.syncAndReturnAll();
System.out.println(result);
//3.lua脚本实例
jedis.set("product_stock_10016", "15");
String script = " local count = redis.call('get',KEYS[1] ) " +
" redis.call('set',KEYS[1], count-ARGV[1]) ";
Object luaResult = jedis.eval(script, Arrays.asList("product_stock_10016"), Arrays.asList("10"));
System.out.println(luaResult);
} catch (Exception e) {
e.printStackTrace();
} finally {
///注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
if (jedis != null) {
jedis.close();
}
}
}
2.Spring封装的RedisTemplate方式连接单节点架构
//redis的使用 亲测有效
1.依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置文件
# redis数据库(默认为0)
spring:
redis:
database: 6
host: localhost # Redis服务器地址
port: 6379 # Redis服务器连接端口
password:
pool.max-active: 8 #连接池最大连接数
pool.max-wait: -1 #连接池最大阻塞等待时间
pool.max-idle: 8 #连接池中的最大空闲连接
pool.min-idle: 0 #连接池中的最小空闲连接
timeout: 5000 #连接超时时间(毫秒)
3.声明
@Autowired
private RedisTemplate redisTemplate;
4.使用(具体使用见下面截图)
添加值:redisTemplate.opsForValue().set(key, validCode, DEFAULT_VALID_CODE_TIME_OUT, TimeUnit.MINUTES);
移除值:redisTemplate.delete(key);
redisTemplate.opsForValue(); //操作字符串
redisTemplate.opsForHash(); //操作hash
redisTemplate.opsForList(); //操作list
redisTemplate.opsForSet(); //操作set
redisTemplate.opsForZSet(); //操作有序set
哨兵架构(注意查看防火墙端口是否允许 26379 26380 26381)
1、Jedis方式连接哨兵架构
@GetMapping("/jedis")
public void testJedis() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
String masterName = "mymaster"; //和sentinel-26379.conf配置文件里面sentinel monitor mymaster 192.168.0.60 6379 2
Set<String> sentinels = new HashSet<>();
sentinels.add(new HostAndPort("192.168.61.148", 26379).toString());
sentinels.add(new HostAndPort("192.168.61.148", 26380).toString());
sentinels.add(new HostAndPort("192.168.61.148", 26381).toString());
//连接池
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, jedisPoolConfig, 3000, null);
Jedis jedis = null;
try {
//从redis连接池里拿出一个jedis
jedis = jedisSentinelPool.getResource();
jedis.set("aaaakey","aaaavalue");
System.out.println(jedis.get("aaaakey"));
} catch (Exception e) {
e.printStackTrace();
} finally {
///注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
if (jedis != null) {
jedis.close();
}
}
}
2.Spring封装的RedisTemplate方式连接哨兵架构
配置文件
spring:
redis:
database: 7
timeout: 5000 #连接超时时间(毫秒)
sentinel: #哨兵模式
master: mymaster #主服务器哨兵名称 和sentinel-26379.conf配置文件里面sentinel monitor mymaster 192.168.0.60 6379 2
nodes: 192.168.61.148:26379,192.168.61.148:26380,192.168.61.148:26381
lettuce:
pool:
max-idle: 50
min-idle: 10
max-active: 100
max-wait: 1000
七。缓存穿透、缓存雪崩和缓存击穿
缓存穿透:指查询一个数据库一定不存在的数据 (传入id为-1,缓存不存在,查数据库,数据库也不存在,这样一直都查询的数据库)
解决办法:数据库也不存在时将id=-1和Null存入缓存,过期设置短一点
布隆过滤器解决缓存穿透
缓存雪崩:缓存集中过期失效 (比如双十一晚上8点迎来一波抢购存入缓存,到了九点全部过期)
解决办法:根据商品的分类设置不同的过期实践
缓存击穿:是指一个key非常热点,在不停的扛着大并发,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库
解决办法:让这个key永不过期
或者互斥锁的办法(此方法只允许一个线程重建缓存, 其他线程等待重建缓存的线程执行完, 重新从缓存获取数据即可)
public void String get(String key) {
// 从Redis中获取数据
String value = redis.get(key);
if (value == null) {
String tempKey = "hot:key:" + key;
// 只允许第一个线程重建缓存(即从数据库读取数据,其他线程都重新走一遍这个方法)
if (redis.set(tempKey, "1", "ex 180", "nx")) {
// 从数据源获取数据并设置到redis
value = db.get(key);
redis.setex(key, timeout, value);
// 删除临时key
edis.delete(tempKey );
}else{
// 其他线程休息50毫秒后重试
Thread.sleep(50);
get(key);
}
}
}