Redis介绍
Redis(全称:Remote Dictionary Server 远程字典服务),是一个key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
Redis内置 复制(replication),LUA脚本,LRU驱动事件,事务(transactions)和不同级别的磁盘持久化(persistence),并通过Redis哨兵(Sentinel)和自动分区(Cluster)提高可用性(high availability)。
读的速度:110000次/s,写的速度81000次/s。
缓存机制
说明:缓存中的数据其实就是数据库数据的备份,缓存机制就是有效的降低用户访问真是物理设备频次。
前提:缓存一般保存到内存中
问题:
- 缓存的内存空间如何维护;
- 如何保持数据的一致性;
- 缓存中的数据如何保证不丢失;
- 如何实现缓存高可用;
Redis安装
- 下载,上传
- 解压
tar -xvf redis.tar.gz
- 编译和安装Redis
在redis根部录下执行make & make install
redis文件说明
- CC C语言文件。
- redis.check.rdg.o 数据持久化文件,将内存中的数据持久化到硬盘
- redis.cli.o 相当于redis客户端,redis是一个服务器,所以需要客户端
- redis.check.aop.o 另外的一种持久化文件
安装报错:
gcc: Command not found
解决办法:
- 安装gcc编译器
yum install gcc -y
jemalloc/jemalloc.h: No such file or directory。
解决办法:
- 网上错误解决办法:
网上大部分解决办法都是错误的,如下文:
(错误解决办法)make MALLOC=libc
- 正确解决办法
正确解决办法(针对2.2以上的版本)
清理上次编译残留文件,重新编译make distclean && make
导致出现这个错误的原因:
错误的本质是我们在开始执行make 时遇到了错误(大部分是由于gcc未安装),然后我们安装好了gcc 后,我们再执行make ,这时就出现了jemalloc/jemalloc.h: No such file or directory。这是因为上次的编译失败,有残留的文件,我们需要清理下,然后重新编译就可以了。
网上的解决办法是有什么错误吗?
网上的解决办法虽然最后也是可以成功安装好 redis ,但是是有一些隐患的,首先我们要知道redis 需要使用内存分配器的, make MALLOC=jemalloc 就是指定内存分配器为 jemalloc ,make MALLOC=libc 就是指定内存分配器为 libc ,这个是有安全隐患的,jemalloc 内存分配器在实践中处理内存碎片是要比libc 好的,而且在README.md 文档也说明到了,jemalloc内存分配器也是包含在源码包里面的,可以在deps 目录下看到 jemalloc 目录。
Redis启动
命令 | 说明 |
---|---|
redis-server | 直接启动出图标,不能其他错做 |
redis-server & | &表示还有其他操作,启动不出图标,默认不能被用户远程访问,保护 模式是开启的 |
redis-server redis.conf | 配置文件开启 |
redis-cli -p 6379 shutdown | 停止 |
redis-cli shutdown | 停止 |
kill -9 8386 | 停止 |
redis-cli -p 6379 | 进入控制台 |
info replication | 查看当前节点状态 |
ps -ef |grep redis | 查看redis状态 |
修改Redis配置文件
- 关闭IP绑定(第69行注释掉)
- 关闭保护模式 (第88行 改为no)
- 开启后台启动(启动时不出现图标,第136行改为yes)
Redis命令
String 类型
命令 | 说明 | 举例 |
---|---|---|
set | 添加key-value | set username admin |
get | 根据key获取数据 | get username |
strlen | 获取key的长度 | strlen key |
exists | 判断key是否存在 | exists name,返回1存在,返回0不存在 |
del | 删除redis中的key | del key |
keys | 用于查询符合条件的key | keys *(查询redis中的全部的key) ;keys n?me(使用占位符获取数据); keys nam*(获取nam开头的数据) |
mset | 赋值多个key-value | mset key1 value1 key2 value2 key3 value3 |
mget | 获取多个key的值 | get key1 key2 |
append | 对某个key的值进行追加 | append key value |
type | 检查某个key的类型 | type key |
select | 切换redis数据库 | select 0-15 redis中一共有16个数据库 |
flushdb | 清空单个数据库 | flushdb |
flushall | 清空全部数据库(慎用) | flushall |
incr | 自动加1 | incr key |
decr | 自动减1 | decr key |
incrby | 指定数值添加 | incrby 10 |
decrby | 指定数值减少 | decrby 10 |
expire | 指定key的失效时间,单位秒 | expire key 20,20秒后失效 |
pexpire | 指定key的失效时间,单位毫秒 | pexpire 200,200毫秒后失效 |
ttl | 检查key的剩余存活时间 | ttl key |
persist | 撤销key的失效时间 | persist key |
Hash类型
说明:可以用散列类型保存对象和属性值
例子:User对象{id:1,name:张三,age:18}
命令 | 说明 | 举例 |
---|---|---|
hset | 为对象添加数据 | hset key field value |
hget | 根据key对象的属性值 | hget key field |
hexists | 判断对象的属性是否存在 | HEXISYS key field |
hdel | 删除Hash中的属性 | hdel user field [field …] |
hgetall | 获取Hash全部元素和值 | HGETALL key |
hkeys | 获取Hash中所有的字段 | HKEY key |
hlen | 获取Hash中所有属性的数量 | hlen key |
hmget | 获取Hash里面指定字段的值 | hmget key field [field …] |
hmset | 为Hash的多个字段设定值 | hmset key field value [field …] |
hsetnx | 设置Hash的一个字段只有当这个字段不存在时有效 | HSETNX key field value |
hstrlen | 获取Hash中指定key的长度 | HSTRLEN key field |
hvals | 获取Hash的所有值 | HVALS user |
List类型
说明:Redis中的LIst几个是双端循环列表
,分别可以从左右两个方向插入数据;
- List集合可以当队列使用,也可以当作栈使用:
- 队列:存入数据的方向和获取数据的方向相反;
- 栈:存入数据的方向和获取数据的方向相同;
命令 | 说明 | 举例 |
---|---|---|
lpush | 从队列的左边入队一个或多个元素 | LPUSH key value |
rpush | 从队列的右边入队一个或多个元素 | RPUSh key value |
lpop | 从队列的左端出队一个元素 | LPOP key |
rpop | 从队列的右端出队一个元素 | TPOP key |
lpushx | 当队列存在时,从队列的左侧入队一个元素 | LPUSHX key value |
rpushx | 当队列存在时,从队列的右侧入队一个元素 | RPUSHX key value |
lrange | 从队列中获取指定返回的元素 | LRANGE key start stop,LRANGE key 0 -1 获取全部队列的数据 |
lrem | 从存于key的列表里移除前count次出现的值为value元素,这个count参数通过下面种方式影响这个操作:count>0,从头向尾部移除值为value的元素;count<0,从尾部向头部移除值为value的元素;count=0,移除所有值为value的元素 | LREM list -2 “hello” 会从存于list的列表里移除最后两个出现的hello。需要注意,如果list里没有存在key就会当作空list处理,所以当key不存在时,这个命令会返回0。 |
Lset | 设置index位置的list元素的值为value | LSET key index value |
Redis事务命令
说明:redis操作可以添加事务的支持,一项任务可以由多个Redis命令完成,如果有一个命令失败导致入库失败时,需要实现事务回滚。
命令 | 说明 | 举例 |
---|---|---|
multi | 标记一个事务开始 | 127.0.0.1:6379> MULTI OK |
exec | 执行所有multi之后发出的命令 | 127.0.0.1:6379> EXEC OK |
discard | 丢失所有multi之后发出的命令 |
Redis案例
添加依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>***</version>
</dependency>
<!--添加spring-datajar包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>***</version>
</dependency>
操作Redis数据库
public class TestRedis {
//String类型
@Test
public void test01() {
Jedis jedis = new Jedis("192.168.31.181", 6379);
jedis.set("username", "admin");
System.out.println(jedis.get("username"));
}
//Hash类型
@Test
public void test02() {
Jedis jedis = new Jedis("192.168.31.181", 6379);
jedis.hset("user", "id", "1");
jedis.hset("user", "name", "小明");
jedis.hset("user", "age", "18");
Map<String, String> user = jedis.hgetAll("user");
System.out.println(user);
}
//List类型
@Test
public void test03() {
Jedis jedis = new Jedis("192.168.31.181", 6379);
jedis.lpush("list", "1,2,3,4,5", "6", "7");
System.out.println(jedis.lpop("list"));
System.out.println(jedis.lpop("list"));
System.out.println(jedis.rpop("list"));
}
}