- 字符串类型 - `String`
- 列表类型 - `Set`
- 有序集合类型 - `Sorted Set`
- 散列类型 - `Hash`
- 集合类型 - `List`
- 缓存
- 任务队列
- 网站访问统计
- 应用排行榜
- 分布式集群架构中的session分离
可以看我这篇文章【Linux学习】 Redis常用的一些指令
Java
平台上使用redis
,肯定需要Jedis
这个客户端。首先在pom
文件中引入Jedis
的依赖 <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
public void methodOne() {
Jedis jedis = new Jedis("100.64.84.47", 6379);
jedis.set("name", "cmazxiaoma");
String value = jedis.get("name");
System.out.println(value);
jedis.close();
}
public void methodTwo() {
//获得连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大连接数
config.setMaxTotal(30);
//设置最大空闲连接数
config.setMaxIdle(10);
//获得连接池
JedisPool jedisPool = new JedisPool(config, "100.64.84.47", 6379);
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String value = jedis.get("name");
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
jedisPool.close();
}
}
}
public class JedisDemo1Test {
private JedisDemo1 demo;
@Before
public void setUp() {
demo = new JedisDemo1();
}
@Test
public void methodOne() throws Exception {
demo.methodOne();
}
@Test
public void methodTwo() throws Exception {
demo.methodTwo();
}
}
Test Case
,测试成功。image.png
Xshell
软件,输入get name
指令,也可以看到输出cmazxiaoma
。image.png
Key
定义的注意点:- 不要过长。
- 不要过短。
- 统一的命名规范。存储
- 二进制安全的,存入和获取的数据相同。
- `Value`最多可以容纳的数据长度是`512M`。存储
- 赋值
image.png
- 取值
image.png
- 删除
image.png
- 数值增减
如果属性不存在的话,那么integer
类型默认为0
。
image.png
如果name
属性的值不能转换成integer
类型,那么会抛出ERR is not an integer or out of range
异常。
image.png
decr
指令也是一样的。
image.png
incrby
、decrby
也是一样的,很简单。
image.png
append
指令可以拼接字符串。
image.png
如果append key cmazxiaoma
。这个key
不存在的话,首先会创建这个key
,然后存入cmazxiaoma
内容,接着输出cmazxiaoma
。
image.png
hset myhash key value
单一赋值、hmset myhash key value key value
多次赋值。image.png
hget myhash key
单一取值、hmget myhash key key
多个取值、hgetall
取出所有key
所对应的值。image.png
hdel myhash key
删除单一的key
。image.png
hdel myhash key key
删除多个的key
。
image.png
del myhash
删除myhash
中所有的key
。
image.png
hincrby myhash key 100
image.png
hexists myhash key
判断key
是否在myhash
中存在,存在返回1
,不存在返回0
。image.png
hlen myhash
获取myhash
中存在key
的数量。image.png
hkeys myhash
获取myhash
中所有的key
。image.png
hvals myhash
获取myhash
中所有的values
。image.png
- `ArrayList`使用数组方式
- `LinkedList`使用双向链表方式两端添加
- 使用`lpush a b c` 命令在左端添加,那么`c`肯定是在最左端。
image.png
- 使用`rpush a b c`命令在右端添加,那么`c`肯定是在最右端。
image.png
- 使用`lpop mylist`弹出`mylist`中头部元素、`rpop mylist2`弹出`mylist2`尾部中的元素。它们都是`3`。
image.png
- 我们接着来查看`mylist`、`mylist2`。
image.png
lrange mylist 0 5
来查看mylist
列表,mylist
插入的方式从头结点开始添加的,那么输出肯定是321abc
。image.png
- 使用`lrange mylist2 0 5`查看`mylist2`列表,`mylist2`插入的方式是从最右端添加的,那么输出肯定是`abc123`
image.png
image.png
- 使用`llen mylist`命令
image.png
- 使用`lpushx mylist x`,使插入的元素在头部位置。
image.png
- 使用`rpushx mylist x`,使插入的元素在尾部位置。
image.png
- 使用`lrem mylist count element`,`count`代表是删除的次数,`element`代表是需要删除的元素。如果`count > 0` 代表删除的方式从头到尾,删除`count`个`element`,`count < 0`代表删除的方式从尾到头,删除`count`个`element`。如果`count = 0`,删除`mylist`中所有和`element`相同的元素。
image.png
image.png
- `lrem mylist 2 test1`
image.png
- `lrem mylist -2 test1`
image.png
- `lrem mylist 0 cmazxiaoma`
image.png
- 在某一个下标位置插入元素。`lset mylist index element`
image.png
- 在目标元素之前插入指定的元素。`linsert mylist before helloworl before_helloworld`
image.png
image.png
- 在目标元素之后插入指定的元素。`linsert mylist helloworld after after_helloworld`
image.png
- 弹出`mylist`中最后一个元素,并插入到`mylist`中的头部。`rpoplpush mylist mylist`
image.png
- `rpoplpush`使用场景
image.png
和List
类型不同的是,Set
集合中不允许出现重复的元素。
sadd myset a b c
,如果我们重复添加相同的元素,肯定是不成功的。比如sadd myset a
。image.png
- 删除 `srem myset a`,删除`myset`中的`a`元素。
image.png
- 查看`myset`中的元素。`smembers myset`
image.png
- 查看指定元素是否是`myset`中的成员。`sismember myset a`,返回`0`代表不存在,返回`1`代表存在。
image.png
smembers myset
sdiff myset2 myset
。myset2
中元素有b,c,d
。myset
中元素有b,c
。它们之间的差集运算结果应该为d
。image.png
- 集合中的交集运算,`sinter myset2 myset`,应该输出`cb`。
image.png
- 集合中的并集运算,`sunion myset2 myse`t,应该输出`cbd`。
image.png
- `scard myset` 查看`myset`有多少个元素。
image.png
- `srandmember myset` 随机返回`myset`中的一个元素。
image.png
- `sdiffstore new_myset myset2 myset` 把`myset`和`myset2`差集元素的结果存储到`new_myset`中。(`sinterstore`, `sunionstore`也是一样的用法)
image.png
- 跟踪一些唯一性的数据。
- 用于维护数据对象之间的关联关系。
SortedSet
中的成员在集合中的位置是有序的。
zadd mysort 70 cmazxiaoma 80 xiaoma 100 doudou
image.png
- `zcard mysort` 获得`mysort`中所有元素的个数
image.png
- 获得`mysort`中`name`为`cmazxiaoma`对应的成绩。`zscore mysort cmazxiaoma`
image.png
zrem mysort cmazxiaoma deli doudou xiaoma
image.png
zrange mysort 0 -1
,输出的key
是按成绩正序排列。image.png
- 如果输出的数据项要带上成绩的话,指令应该是`zrange mysort 0 -1 withscores`
image.png
- 如果输出的数据项想按成绩逆序排序,那么就应该`zrevrange mysort 0 -1 withscores`
image.png
- 如果想按排名范围进行删除的话,那么应该`zremrangebyrank mysort 0 2`
image.png
- 如果想按成绩范围进行删除的话,那么应该`zremrangebyscore mysort 0 10`。顾名思义删除成绩在`0-10`之内的数据项。
image.png
- 查看分数在`0-10`之内的学生信息,`zrangebyscore mysort 0 10 withscores`
image.png
- 查看分数在`0-100`之内且在第`1`行-第`2`行的学生信息。`zrangebyscore mysort 0 100 withiscores limit 0 2`
image.png
- 给`cmazxiaoma`的成绩加`100`分。`zincrby mysort cmazxiaoma 100`
image.png
- 查看成绩`0-10`之间的学生的个数。`zcount mysort 0 10`
image.png
Sorted Set
使用场景- 如大型在线游戏积分排行榜
- 构建索引数据
key *
获取所有redis中的keyimage.png
keys my*
获取所有redis
中以my
开头的key
image.png
exists mylist
查看redis
中是否存在mylis
t,0
代表不存在,1
代表存在。image.png
rename name new_name
给名字为name
的数据结构重命名为new_name
image.png
expire new_name 10
设置redis
中new_name
过期时间,通过ttl new_name
看到其距离过期的时间。image.png
type mylist
,可以查看mylist
对应的数据结构类型。image.png
Redis
相关的特性:- 多数据库
- `Redis`事务一个
image.png
0
号的数据库中某些key
移动到第1
号数据库里面,那么我们该怎么做呢。通过move cmazxiaoma_test_mayday_5 1
就可以完成。image.png
multi
、exec
、discard
来完成事务操作。事务执行期间,Redis
不会为其他客户端提供任何服务,以保证事务中的所有命令原子执行。multi
相当于开启事务,exec
相当于提交,discard
相当于回滚。incr num
2
次,按理来说,get num
应该等于4
。redis第一个客户端.png
get num
,发现num
还是2
。那么证明了我们的结论:事务执行期间,Redis
不会为其他客户端提供任何服务,以保证事务中的所有命令原子执行。image.png
image.png
get num
,发现可以num
的值得到了更新。image.png
set user cmazxiaoma
,接着开启事务,在事务中set user xiaoma
,然后进行回滚操作,发现 get user
依然是cmazxiaoma
。image.png
Redis
的性能体现在它把数据都保存在内存当中。我们把内存中的数据同步到硬盘当中的操作称之为持久化。
Redis
持久化方式:- `RDB`方式,在指定的时间内,把内存中的数据快照写入到硬盘当中。
- `AOF`方式,将以日志的形式记录服务器所处理的每一个操作。当`Redis`服务器启动之初,它会读取该`aof`文件,会重新构建我们的数据库。保证我们启动之后,保证数据的完整性。
- 无持久化,我们可以通过配置禁止`Redis`服务器的持久化,我们认为`Redis`就是缓存的一种机制了。
- 同时使用。
- 默认情况下,每隔一段时间`redis`服务器程序会自动对数据库做一次遍历,把内存快照写在一个叫做`"dump.rdb"`的文件里,这个持久化机制叫做`SNAPSHOT`。有了`SNAPSHOT`后,如果服务器宕机,重新启动`redis`服务器时,`redis`会自动加载`"dump.rdb"`,将数据库状态恢复上一次`SNAPSHOT`的状态。
- `Redis`服务器初始化过程中,设定了定时时间,每隔一段时间就会触发持久化操作,进入定时事件处理程序中,就会`fork`出子进程来进行持久化操作。
- `Redis`服务器预设了`save`指令,客户端可要求服务器进程中断服务,执行持久化操作。
- 我们可以通过`vim /etc/redis.conf`打开配置文件,可以看到以下配置。
image.png
- 同时我们还可以看到内存快照输出在`file`文件名。
image.png
优缺点:
- 如果数据集很大,`RDB`相对于`AOF`启动效率很更高。
- 如果想保证数据的高可用性,最大限度的避免数据的丢失,`RDB`将不是一个好的选择。因为系统在定时持久化操作之前,还没来得及在硬盘写入数据就发生宕机的话,就造成了数据的丢失。
- `RDB`通过`fork`出子线程来完成数据持久化操作,如果当数据集很大的时候,可能会导致服务器停止几百`ms`,或者几`s`。
RDB.png
AOF
(append only file
):Redis
服务器而言,其缺省的机制是RDB
,如果需要使用AOF
,则需要修改appendonly no
改成appendonly yes
。Redis
在每一次收到数据修改的命令之后,都会将其追加到AOF
文件中。在Redis
下一次重新启动时,需要加载AOF
文件中的信息来构建最新的数据到内存中。image.png
image.png
Redis
会重写写操作集。3
种同步策略,每秒同步,每修改同步,不同步。 每秒同步也是异步完成的,效率也非常高。缺点是一旦系统发生宕机的现象,那么这一秒中的修改的数据就会发生丢失。每修改同步,我们可以视为同步持久化。每一次发生数据的变化,就会立即的记录在磁盘,这种效率很低,但是很安全。append
追加的模式,就算系统发生宕机,也不会影响我们日志文件中已经存在的内容。然而我们本次操作中,只写入了一半数据就出现了系统崩溃的问题。在Redis下一次启动之前,我们可以通过"redis-check-aof --fix <filename>"
命令来修复坏损的AOF
文件,解决数据一致性的问题。AOF
文件通常要大于RDB
文件。AOF
在运行效率上往往会慢于RDB
。AOF.png
RDB
和AOF
的区别
前者是保存了数据本身,而后者是记录了数据的变更。这篇文章最后在网吧完成的,勿以善小而不为。