Redis模式
1. 单实例模式
单实例一般 作为学习使用。只需要一台服务就可以了。
2. 哨兵模式
该模式 使用 1主多从 ,保证了 高可用行。 当 主服务器 不可用时,完成自动切换。
集群配置:
redis.config配置
redis主:
port 6379
redis从:
port 6380
slaveof 127.0.0.1 6379
启动:
redis-server.exe redis.conf
连接: redis-cli.exe -p 6379
查看主从信息:
info replication
sentinel的 redis.config配置:
port 26379
sentinel monitor mymaster 127.0.0.1 6380 1
启动
redis-server.exe redis.conf --sentinel
连接: redis-cli.exe -p 26379
查看监控信息:
info sentinel
spring boot 中 使用 哨兵模式的 Java配置,其他不变。
@Bean
public JedisConnectionFactory redisConnectionFactory() {
/**哨兵模式**/
RedisSentinelConfiguration config = new RedisSentinelConfiguration();
RedisServer sentinel = new RedisServer("127.0.0.1",26379);
config.setSentinels(Arrays.asList(sentinel));
config.setMaster("mymaster");
return new JedisConnectionFactory(config);
}
3 集群模式
三主:
每个节点的配置:
节点1:
port 7001
cluster-enabled yes
节点2:
port 7002
cluster-enabled yes
节点2:
port 7003
cluster-enabled yes
每个节点启动服务
redis-server.exe redis.conf
启动后,创建集群:
redis-cli.exe --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
执行这个命令,可以完成集群节点添加和槽位分配,也就是下面两个命令:
cluster meet
cluster addslots
可以使用 cluster info , cluster nodes 来查看集群信息
此时只有主节点,没有设置从节点。如果其中一个主节点服务挂了,那整个集群也不可用了。
三主三从:
重复上述操作,需要6个redis服务实例,启动后执行:
redis-cli.exe --cluster create --cluster-replicas 1 127.0.0.1:7001 127.0.0.2:7002 127.0.0.1:7003 127.0.0.1:27001 127.0.0.1:27002 127.0.0.1:27003
--cluster-replicas 1 表示 1个副本
此时,如果某个 主节点服务挂了,那么 集群会自动 将该主节点的 从节点 升级为主节点,集群服务可以正常使用。当该主节点服务重启后,会作为集群的从节点服务。
在实际的使用中,用的都是集群的方式。哨兵模式还没有使用过。
spring boot中的配置:
@Bean
public JedisConnectionFactory redisConnectionFactory() {
// 集群模式
RedisClusterConfiguration config = new RedisClusterConfiguration(Arrays.asList("127.0.0.1:7001","127.0.0.1:7002","127.0.0.1:7003","127.0.0.1:27001","127.0.0.1:27002","127.0.0.1:27003"));
return new JedisConnectionFactory(config);
}
Spring Boot 项目使用 Redis
1. pom.xml 添加依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.1.8.RELEASE</version>
</dependency>
或者
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
引入redis依赖包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
2. 连接
// 配置类接口,有 哨兵、单实例、集群等实现类
org.springframework.data.redis.connection.RedisConfiguration
// 两个连接接口
org.springframework.data.redis.connection.RedisConnection
org.springframework.data.redis.connection.RedisConnectionFactory
// 连接工厂实现类,有不同的构造方法
org.springframework.data.redis.connection.jedis.JedisConnectionFactory
// redis 操作类
// RedisTemplate和StringRedisTemplate 如果序列化方式不一样,则互相取不到对方设置的数据
// 一般 直接使用 StringRedisTemplate
org.springframework.data.redis.core.RedisTemplate # 默认JDK序列化
org.springframework.data.redis.core.StringRedisTemplate #String序列化
3. 示例
@Component
public class RedisConfig {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("127.0.0.1", 6379);
return new JedisConnectionFactory(config);
}
@Bean
public RedisTemplate redisTemplate(JedisConnectionFactory configuration){
RedisTemplate redisTemplate = new RedisTemplate();
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
redisTemplate.setValueSerializer(StringRedisSerializer.UTF_8);
// redisTemplate.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
// redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8);
redisTemplate.setHashValueSerializer(StringRedisSerializer.UTF_8);
// redisTemplate.afterPropertiesSet();
redisTemplate.setConnectionFactory(configuration);
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate(JedisConnectionFactory configuration){
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(configuration);
return redisTemplate;
}
}
@Service
public class RedisService {
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
public void test(){
redisTemplate.opsForHash().put("redis:test:one","cat1", JSON.toJSONString(new Cat("c1",2)));
stringRedisTemplate.opsForHash().put("redis:test:one","cat2", JSON.toJSONString(new Cat("c1",2)));
}
}
Redis常用API
String
1. 设置有一个特点,可以设置过期时间
2. 可以追加或者截取某个字符串返回
3. 可以原子增加
4. SET if Not eXists
设置值,根据选项返回原值
SET
SET key value [ NX | XX] [GET] [ EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
The SET command supports a set of options that modify its behavior:
NX -- Only set the key if it does not already exist.
XX -- Only set the key if it already exist.
GET -- Return the old string stored at key, or nil if key did not exist. An error is returned and SET aborted if the value stored at key is not a string.
EX seconds -- Set the specified expire time, in seconds.
PX milliseconds -- Set the specified expire time, in milliseconds.
EXAT timestamp-seconds -- Set the specified Unix time at which the key will expire, in seconds.
PXAT timestamp-milliseconds -- Set the specified Unix time at which the key will expire, in milliseconds.
KEEPTTL -- Retain the time to live associated with the key.
SETEX
SETEX key seconds value
PSETEX
PSETEX key milliseconds value
SETNX
SETNX key value
SETNX is short for "SET if Not eXists"
MSET
MSET key value [ key value ...]
MSETNX
MSETNX key value [ key value ...]
给一个已经存在的字符串追加字符串
APPEND
APPEND key value
加1
INCR
INCR key
加n
INCRBY
INCRBY key increment
INCRBYFLOAT
INCRBYFLOAT key increment
减1
DECR
DECR key
减n
DECRBY
DECRBY key decrement
GET
GET key
查询并删除
GETDEL
GETDEL key
查询并设置过期时间
GETEX
GETEX key [ EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | PERSIST]
The GETEX command supports a set of options that modify its behavior:
EX seconds -- Set the specified expire time, in seconds.
PX milliseconds -- Set the specified expire time, in milliseconds.
EXAT timestamp-seconds -- Set the specified Unix time at which the key will expire, in seconds.
PXAT timestamp-milliseconds -- Set the specified Unix time at which the key will expire, in milliseconds.
PERSIST -- Remove the time to live associated with the key
返回指定下标下的字符串,类似 subString
GETRANGE
GETRANGE key start end
获取值并设置新的值
GETSET
GETSET key value
LCS
MGET
MGET key [key ...]
SETRANGE
SETRANGE key offset value
类似于replace
STRLEN
STRLEN key
SUBSTR
SUBSTR key start end
Hash
对于增加,有三类情况:
1. 单个增加k-v 或者 批量增加 k-v
2. 原子性的修改 v
3. putIfAbsent
删除只提供了一个方法
单个删除k 或者批量删除k
查询的几种情况:
1. 查询单个k
2. 批量查询多个 k
3. 一次查询所有的 k-v
4. 查询所有的 k
5. 查询所有的 v
6. 判断某个k是否存在
HSET
HSET key field value [ field value ...]
Time complexity: O(1) for each field/value pair added, so O(N) to add N field/value pairs when the command is called with multiple field/value pairs.
The number of fields that were added
HMSET
HMSET key field value [ field value ...]
Time complexity: O(N) where N is the number of fields being set
Simple string reply
deprecated
HSETNX
HSETNX key field value
Time complexity: O(1)
Sets field in the hash stored at key to value, only if field does not yet exist. If key does not exist, a new key holding a hash is created. If field already exists, this operation has no effect
1 if field is a new field in the hash and value was set.
0 if field already exists in the hash and no operation was performed
类似于putIfAbsent
HINCRBY
HINCRBY key field increment
Time complexity: O(1)
the value at field after the increment operation
HINCRBYFLOAT
HINCRBYFLOAT key field increment
Time complexity: O(1)
the value of field after the increment
HDEL
HDEL key field [field ...]
Time complexity: O(N) where N is the number of fields to be removed
Integer reply: the number of fields that were removed from the hash, not including specified but non existing fields.
HGET
HGET key field
Time complexity: O(1)
Bulk string reply: the value associated with field, or nil when field is not present in the hash or key does not exist
HMGET
HMGET key field [field ...]
Time complexity: O(N) where N is the number of fields being requested
list of values associated with the given fields, in the same order as they are requested.
HGETALL
HGETALL key
Time complexity: O(N) where N is the size of the hash
list of fields and their values stored in the hash, or an empty list when key does not exist
HKEYS
HKEYS key
Time complexity: O(N) where N is the size of the hash.
list of fields in the hash, or an empty list when key does not exist
HVALS
HVALS key
Time complexity: O(N) where N is the size of the hash.
list of values in the hash, or an empty list when key does not exist
HLEN
HLEN key
Time complexity: O(1)
number of fields in the hash, or 0 when key does not exist
HRANDFIELD
HRANDFIELD key [ count [WITHVALUES]]
Available since: 6.2.0
Time complexity: O(N) where N is the number of fields returned
HSCAN
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
HSTRLEN
HSTRLEN key field
Time complexity: O(1)
the string length of the value associated with field, or zero when field is not present in the hash or key does not exist at all
HEXISTS
HEXISTS key field
Time complexity: O(1)
1 if the hash contains field.
0 if the hash does not contain field, or key does not exist
List
1. 从队首操作
2. 从队尾操作
3. 入队、出队、队列之间元素转移
4. 阻塞操作
5. 下标操作
加入元素:
插入元素,后面的元素放在前面
LPUSH
LPUSH key element [element ...]
Elements are inserted one after the other to the head of the list
RPUSH
RPUSH key element [element ...]
Elements are inserted one after the other to the tail of the list, from the leftmost element to the rightmost element
只有当key存在才添加元素
LPUSHX
LPUSHX key element [element ...]
only if key already exists
只有当key存在才添加元素
RPUSHX
RPUSHX key element [element ...]
在pivot 之前或者之后插入 element
LINSERT
LINSERT key BEFORE | AFTER pivot element
在 index位置添加元素
LSET
LSET key index element
弹出元素:
弹出第一个元素
LPOP
LPOP key [count]
弹出最后的元素
RPOP
RPOP key [count]
LMPOP
LMPOP numkeys key [key ...] LEFT | RIGHT [COUNT count]
LPOS
LPOS key element [RANK rank] [COUNT num-matches] [MAXLEN len]
LPOS key element 返回第一个元素的下标
LPOS key element [RANK rank] 返回第 rank 个元素的下标, 如果rank 是负数,则从尾部开始查找
COUNT 返回的个数
移除指定个数的元素
LREM
LREM key count element
count > 0: Remove elements equal to element moving from head to tail.
count < 0: Remove elements equal to element moving from tail to head.
count = 0: Remove all elements equal to element.
LTRIM
LTRIM key start stop
队列之间的操作
原子操作 将source的left|right 元素 移动到 destination的 left|right
LMOVE
LMOVE source destination LEFT | RIGHT LEFT | RIGHT
弹出source最后的元素 加入到 destination 第一个位置
RPOPLPUSH
RPOPLPUSH source destination
返回index位置的元素
LINDEX
LINDEX key index
返回元素个数
LLEN
LLEN key
返回指定下标范围的元素
LRANGE
LRANGE key start stop
阻塞操作
BLMOVE
BLMPOP
BLPOP
BRPOP
BRPOPLPUSH
Set
1. 元素的基本操作
2. 集合之间的操作
添加元素,若元素已存在,则忽略
SADD
SADD key member [member ...]
判断元素是否存在集合中
SISMEMBER
SISMEMBER key member
批量判断元素是否存在集合中
SMISMEMBER
SMISMEMBER key member [member ...]
返回指定数量的元素
SRANDMEMBER
SRANDMEMBER key [count]
1. SRANDMEMBER key 随机返回key的一个元素
2. SRANDMEMBER key count ,count是正数,返回的数量为count 或者 小于count
3. SRANDMEMBER key count ,count是负数,返回的数量 一定是 count,如果不够count,则同一个元素会多次反回
返回集合所有元素
SMEMBERS
SMEMBERS key
移除指定的元素
SREM
SREM key member [member ...]
随机移除 key 的若干个元素
SPOP
SPOP key [count]
返回元素个数
SCARD
SCARD key
将元素从 source 移动到 destination
SMOVE
SMOVE source destination member
返回第一个key 和其他key 不同的元素
SDIFF
SDIFF key [key ...]
返回第一个key 和其他key 不同的元素,并存储到destination
SDIFFSTORE
SDIFFSTORE destination key [key ...]
将 多个集合 并集
SUNION
SUNION key [key ...]
将 多个集合 并集,并存储在destination
SUNIONSTORE
SUNIONSTORE destination key [key ...]
返回所有key之间的交集
SINTER
SINTER key [key ...]
返回所有key之间的交集,并存储到destination
SINTERSTORE
SINTERSTORE destination key [key ...]
SINTERCARD
SINTERCARD numkeys key [key ...] [LIMIT limit]
SSCAN