1、redis当中对字符串string的操作
下表列出了常用的 redis 字符串命令
CRUD | 功能 | 示例 |
增 | 添加字符串 | set hello world |
设置多个KV | mset AA AAA BB BBB CC CCC | |
设置过期时间 | setex hello1 5 word1 | |
key不存在时设置 | setnx hello2 word22 | |
查 | 查询字符串 | get hello |
查询部分 | getrange hello 0 2 | |
查询多key | mget hello hello2 hello3 | |
查询长度 | strlen hello | |
改 | 修改字符串 | set hello world2 |
追加 | append hello 333 | |
删 | 删除字符串 | del hello |
其他 | 现获取后设置 | getset hello word222 |
替换 | setrange hello22 2 AA | |
累加1 | incr number | |
累加N | incrby number 10 | |
累加小数 | incrbyfloat number 0.5 | |
减一(只对integer有效) | decr number | |
减N | decrby number 3 |
2、redis当中对hash列表的操作
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)
下表列出了 redis hash 基本的相关命令:
CRUD | 功能 | 示例 |
增 | 添加一个hash列表 | hset hkey1 name zhangsan |
不存在时添加 | hsetnx hkey2 name lisi | |
一次设置多个值 | hmset hkey3 name wangwu age 20 sex 1 | |
查 | 查看数据 | hget hkey1 name |
查看是否存在 | hexists hkey3 name | |
查询key下所有值 | hgetall hkey3 | |
查询key内所有的字段 | hkeys hkey3 | |
查询key的数据量 | hlen hkey3 | |
查询某一key内多字段的值 | hmget hkey3 name age | |
改 | 修改数据 | hset hkey1 name zhangsan2 |
删 | 删除key中的数据 | hdel hkey3 sex |
其他 | 数据累加(1-N) | hincrby hkey number1 10 |
累加小数 | hincrbyfloat hkey number1 0.5 |
3、redis当中对list列表的操作
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
下表列出了列表相关的基本命令
CRUD | 功能 | 示例 |
增 | 添加一个或多个值到列表 | lpush lkey1 zhangsan lisi |
将一个值插入到已存在的列表头部 | lpushx lkey1 wangwuxxx | |
向已经存在的列表中插入数据(右边插入) | rpush lkey1 AA BB | |
将一个值插入到已存在的列表尾部 | rpushx lkey1 ccc | |
在某一数据之前插入 | linsert lkey1 before lisi lisibefore | |
在某一数据之后插入 | linsert lkey1 after lisi lisiafter | |
查 | 查询list中所有数据 (-1表示所有) | lrange lkey1 0 -1 |
通过索引查询数据 | lindex lkey1 0 | |
查询列表长度 | llen lkey1 | |
改 | 通过索引修改数据 | lset lkey1 5 eee |
删 | 数据修剪(保留) | ltrim lkey1 4 6 |
删除指定key数据 | del lkey1 | |
其他 | 移出并获取列表的第一个元素 | lpop lkey1 |
移出并获取列表的最后一个元素 | rpop lkey1 | |
移除列表的最后一个元素,并将该元素添加到另一个列表并返回 | rpoplpush lkey1 lkey2 |
4、redis操作set集合
redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
下表列出了 Redis 集合基本命令:
CRUD | 功能 | 示例 |
增 | 向集合添加一个或多个数据 | sadd skey1 zhangsan lisi
sadd skey2 wangwu lisi |
查 | 查询集合所有数据 | smembers skey1 |
查询集合内数据总量 | scard skey1 | |
查询两个集合的差值 | sdiff skey1 skey2 | |
查询差值并将结果写入新集合 | sdiffstore skey3 skey1 skey2 | |
查询两个集合交集 | sinter skey1 skey2 | |
查询两个集合交集结果写入新集合 | sinterstore skey4 skey1 skey2 | |
查询某一数据是否包含在集合中 | sismember skey1 zhangsan | |
返回集合内随机的N个数据 | srandmember skey2 2 | |
查询并集 | sunion skey1 skey2 | |
查询并集结果写入新集合 | sunionstore skeyn skey1 skey2 | |
改 | 将数据在一个集合移动到另一个集合 | smove skey1 skey2 zhangsan |
删 | 移除结果中的某个数据 | srem skey2 zhangsan |
5、redis中对key的操作
下表给出了与 Redis 键相关的基本命令:
CRUD | 功能 | 示例 |
查 | 查询所有符合模式的key | Keys * |
查询剩余过期时间(毫秒) | pttl hkey1 | |
查询剩余过期时间(秒) | ttl hkey1 | |
在数据库中随机回返一个key | randomkey | |
查询key对应数据的类型 | Type hkey1 | |
改 | 对key进行重命名 | Rename hkey1 hkey10 |
删 | 删除存在的key | del BB |
其他 | 判断key是否存在 | exists AA |
为key 设置超时时间 | expire AA 10 | |
为key 设置超时时间(毫秒) | pexpire CC 10000 | |
移除key的过期时间 | persist hkey1 |
6、redis当中的数据库
Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念。
Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与我们熟知的在一个关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一个独立的数据库。
每个数据库对外都是一个从0开始的递增数字命名,Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过配置databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库,如要选择1号数据库:
node01:6379> select 1
node01:6379[1]> keys *
清空redis数据库当中的数据
node01:6379> flushdb
清空所有redis数据库当中的数据
node01:6379> flushall
redis的javaAPI操作
redis不仅可以通过命令行进行操作,同时redis也可以通过javaAPI进行操作,我们可以通过使用javaAPI来对redis数据库当中的各种数据类型进行操作
第一步:创建maven工程并导入jar包
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- <verbal>true</verbal>-->
</configuration>
</plugin>
</plugins>
</build>
第二步:连接以及关闭redis客户端
private JedisPool jedisPool;
private JedisPoolConfig config;
@BeforeTest
public void redisConnectionPool(){
config = new JedisPoolConfig();
config.setMaxIdle(10);
config.setMaxWaitMillis(3000);
config.setMaxTotal(50);
config.setMinIdle(5);
jedisPool = new JedisPool(config, "node01", 6379);
}
@AfterTest
public void closePool(){
jedisPool.close();
}
第三步:redis的javaAPI操作
/**
* 添加string类型数据
*/
@Test
public void addStr(){
Jedis resource = jedisPool.getResource();
//添加
resource.set("jediskey", "jedisvalue");
//查询
String jediskey = resource.get("jediskey");
System.out.println(jediskey);
//修改
resource.set("jediskey","jedisvalueUpdate");
//删除
resource.del("jediskey");
//实现整型数据的增长操作
resource.incr("jincr");
resource.incrBy("jincr",3);
String jincr = resource.get("jincr");
System.out.println(jincr);
resource.close();
}
操作hash列表类型数据
/**
* 操作hash类型数据
*/
@Test
public void hashOperate(){
Jedis resource = jedisPool.getResource();
//添加数据
resource.hset("jhsetkey","jmapkey","jmapvalue");
resource.hset("jhsetkey","jmapkey2","jmapvalue2");
//获取所有数据
Map<String, String> jhsetkey = resource.hgetAll("jhsetkey");
for (String s : jhsetkey.keySet()) {
System.out.println(s);
}
//修改数据
resource.hset("jhsetkey","jmapkey2","jmapvalueupdate2");
Map<String, String> jhsetkey2 = resource.hgetAll("jhsetkey");
for (String s : jhsetkey2.keySet()) {
System.out.println("修改数据打印"+s);
}
//删除数据
resource.del("jhsetkey");
Set jhsetkey1 = resource.keys("jhsetkey");
for (String result : jhsetkey1) {
System.out.println(result);
}
}
操作list类型数据
/**
* 操作list类型的数据
*/
@Test
public void listOperate(){
Jedis resource = jedisPool.getResource();
//从左边插入元素
resource.lpush("listkey","listvalue1","listvalue1","listvalue2");
//从右边移除元素
resource.rpop("listkey");
//获取所有值
List listkey = resource.lrange("listkey", 0, -1);
for (String s : listkey) {
System.out.println(s);
}
resource.close();
}
操作set类型的数据
/**
* set类型数据操作
*/
@Test
public void setOperate(){
Jedis resource = jedisPool.getResource();
//添加数据
resource.sadd("setkey", "setvalue1", "setvalue1", "setvalue2", "setvalue3");
//查询数据
Set setkey = resource.smembers("setkey");
for (String s : setkey) {
System.out.println(s);
}
//移除掉一个数据
resource.srem("setkey","setvalue3");
resource.close();
}
redis的持久化
由于redis是一个内存数据库,所有的数据都是保存在内存当中的,内存当中的数据极易丢失,所以redis的数据持久化就显得尤为重要,在redis当中,提供了两种数据持久化的方式,分别为RDB以及AOF,且redis默认开启的数据持久化方式为RDB方式
Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据。可以在配置文件中配置Redis进行快照保存的时机
RDB方案优点
对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。
每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。
使用RDB文件进行数据恢复比使用AOF要快很多
RDB方案缺点
快照是定期生成的,所以在Redis crash(崩溃)时或多或少会丢失一部分数据。
如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。
AOF方案介绍:
采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。AOF默认是关闭的,如要开启,进行如下配置:
appendonly yes
AOF提供了三种fsync配置,always/everysec/no,通过配置项[appendfsync]指定:
appendfsync no:不进行fsync,将flush文件的时机交给OS(操作系统)决定,速度最快
appendfsync always:每写入一条日志就进行一次fsync操作,数据安全性最高,但速度最慢
appendfsync everysec:折中的做法,交由后台线程每秒fsync一次
AOF优点:
- 最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据
- AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。
- AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。
AOF的缺点:
1、AOF文件通常比RDB文件更大
2、性能消耗比RDB高
3、数据恢复速度比RDB慢
//程序入口
public static void main(String[] args) {
//设置数据库连接池
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//设置连接池的最大连接数
jedisPoolConfig.setMaxTotal(50);
//设置最大空闲数量
jedisPoolConfig.setMaxIdle(10);
//设置最大小空闲数量
jedisPoolConfig.setMaxIdle(5);
//连接超时时间(最大等待时间)
jedisPoolConfig.setMaxWaitMillis(30);
//哨兵信息
HashSet sentinels = new HashSet<>(Arrays.asList("node01:26379", "node02:26379", "node03:26379"));
//获取redis连接池
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig);
//获取连接对象
Jedis jedis = pool.getResource();
//通过对象调用api
String string9999 = jedis.get("string9999");
System.out.println(string9999);
jedis.close();
}
文章评论