一.简介与安装
Redis是c语言开发的。(装c语言环境、解压、编译、安装)端口号6379
很多项目中,为了缓解我们服务器与数据库的压力,我们使用缓存。
安装redis需要c语言的编译环境。如果没有gcc需要在线安装。yum install gcc-c++
安装步骤:
第一步:redis的源码包上传到linux系统。
第二步:解压缩redis。
第三步:编译。进入redis源码目录。make (c语言项目需要编译)
第四步:安装。make install PREFIX=/usr/local/redis
PREFIX参数指定redis的安装目录。一般软件安装到/usr目录下
前端启动:在redis的安装目录下的src目录直接启动redis-server(叫前端启动是因为会占用我们的命令号,命令号就无法使用了 不推荐) 使用ctrl+c退出
[root@localhost bin]# ./redis-server
后台启动(需要配置文件):
把解压出来的文件复制到 我们的安装目录的bin文件中并且修改配置文件
/root/redis-3.0.0/redis.conf复制到/usr/local/redis/bin目录下
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis/bin/
修改配置文件:
加载该配置文件启动 :[root@localhost bin]# ./redis-server redis.conf
查看redis进程:
[root@localhost bin]# ps aux|grep redis
root 5190 0.1 0.3 33936 1712 ? Ssl 18:23 0:00 ./redis-server *:6379
root 5196 0.0 0.1 4356 728 pts/0 S+ 18:24 0:00 grep redis
关闭服务 kill + 端口号 或者kill + 端口号 + -9 强制关闭
或者使用reids-cli客户端断臂 ./redis-cli/ shutdown
二.redis操作与使用
使用./redis-cli 命令客户端连接哪个redis服务 默认端口号为6379
也可以指定ip和端口号 ./redis-cli -h 192.168.25.162 -p 6379
具体数据操作见: https://blog.csdn.net/afdasfggasdf/article/details/84135841
三.redis的持久化方案
Redis的所有数据都是保存到内存中的。
Rdb:快照形式,定期把内存中当前时刻的数据保存到磁盘。Redis默认支持的持久化方案。RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
aof形式:append only file。把所有对redis数据库操作的命令,增删改操作的命令。保存到文件中。数据库恢复时把所有的命令执行一遍即可。(默认不开启 每秒存一次消耗内存)
在redis.conf配置文件中配置。
Rdb:
Aof的配置 appendonly改为 yes就可以了:
两种持久化方案同时开启使用aof文件来恢复数据库。
四.redis集群
redis-cluster架构
只能是单数 因为有投票机制
架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点(不关有多少redis都只有16384个节点)最多有16384各redis服务器
至少需要3个redis节点,那么每一个节点还需要一个备份服务器,所以至少需要6个redis服务
1、使用ruby脚本搭建集群。需要ruby的运行环境。
安装ruby
yum install ruby
yum install rubygems
- 安装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...
[root@localhost ~]#
[root@localhost ~]# cd redis-3.0.0/src
[root@localhost src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 Apr 1 2015 redis-trib.rb
第一步:创建6个redis实例,每个实例运行在不同的端口。需要修改redis.conf配置文件。配置文件中还需要把cluster-enabled yes前的注释去掉。redis.conf中更改redis的端口号
第二步:启动每个redis实例。
第三步:使用ruby脚本搭建集群(src目录下官方给出的解决方案)。
/redis-trib.rb create --replicas 1 192.168.25.153:7001 192.168.25.153:7002 192.168.25.153:7003 192.168.25.153:7004 192.168.25.153:7005 192.168.25.153:7006
在不同服务器上,关闭防火墙的情况下,在任意服务器上执行一边就可以了,
连接集群
redis01/redis-cli -p 7002 -c -c表明你连接的是集群,否则如果计算在其他的redis上那么就会报错
五.jedis的使用
maven导入包jedis
<!-- Redis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
连接单版本 使用连接池
public void testJedisPool() throws Exception {
// 第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。
JedisPool jedisPool = new JedisPool("192.168.25.153", 6379);
// 第二步:从JedisPool中获得Jedis对象。
Jedis jedis = jedisPool.getResource();
// 第三步:使用Jedis操作redis服务器。
jedis.set("jedis", "test");
String result = jedis.get("jedis");
System.out.println(result);
// 第四步:操作完毕后关闭jedis对象,连接池回收资源。
jedis.close();
// 第五步:关闭JedisPool对象。
jedisPool.close();
}
连接集群版
public void testJedisCluster() throws Exception {
// 第一步:使用JedisCluster对象。需要一个Set<HostAndPort>参数。Redis节点的列表。
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.25.153", 7001));
nodes.add(new HostAndPort("192.168.25.153", 7002));
nodes.add(new HostAndPort("192.168.25.153", 7003));
nodes.add(new HostAndPort("192.168.25.153", 7004));
nodes.add(new HostAndPort("192.168.25.153", 7005));
nodes.add(new HostAndPort("192.168.25.153", 7006));
JedisCluster jedisCluster = new JedisCluster(nodes);
// 第二步:直接使用JedisCluster对象操作redis。在系统中单例存在。
jedisCluster.set("hello", "100");
String result = jedisCluster.get("hello");
// 第三步:打印结果
System.out.println(result);
// 第四步:系统关闭前,关闭JedisCluster对象。
jedisCluster.close();
}
技巧:redis单机版与集群版的转换,因为jedis与jedisCluster都实现了JedisClient类,这样我们只需要声明一个jedisclient接口,通过更改配置文件的方式就可以让jedis在集群和单机版之间相互切换了,并且通过集成jedisclient接口,我们还可以定义自己想要的方法。
这里附上写好的redis集群版切换接口以及实现类:
https://download.csdn.net/download/afdasfggasdf/10792766
package cn.txj.utils.redis;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class JedisClientPool implements JedisClient {
@Autowired
private JedisPool jedisPool;
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
}
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
@Override
public Boolean exists(String key) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.exists(key);
jedis.close();
return result;
}
@Override
public Long expire(String key, int seconds) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.expire(key, seconds);
jedis.close();
return result;
}
@Override
public Long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
}
@Override
public Long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
}
@Override
public Long hset(String key, String field, String value) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hset(key, field, value);
jedis.close();
return result;
}
@Override
public String hget(String key, String field) {
Jedis jedis = jedisPool.getResource();
String result = jedis.hget(key, field);
jedis.close();
return result;
}
@Override
public Long hdel(String key, String... field) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hdel(key, field);
jedis.close();
return result;
}
}
注意事项:
1.如果redis获取不到数据,那么返回值为null
2.判断是否存在jedis.exists("");
3.删除jedis.del("jedis");
4.设置过期时间jedis.setex(key, seconds, value); 过期时间为秒
jedis.expire("key", 100);
// NX是不存在时才set, XX是存在时才set, EX是秒,PX是毫秒
jedisCluster.set(key, value, "NX", "EX", expireSecond);
5.获得失效时间jedis.ttl("key"); 返回-1为永久 -2为不存在