redis
是什么
redis(Remote Dictionary Server),远程字典服务。
是一个开源的,基于内存可持久化的日志型,Key-Value数据库,提供多种语言API。被人们成为结构化数据库
https://github.com/MicrosoftArchive/redis/releases
做什么
读11w次/s,写8.1w次/s
1、内存存储、持久化,内存中是断电即失,所以持久化很重要(rdb、aof)
2、效率高,可用作高度缓存
3、发布订阅系统
4、地图信息分析
5、计数器、计时器等
特性
1、多样的数据类型
2、持久化
3、集群
4、事务
基础
默认有16个数据库,默认使用第1个。
// 切换数据库
select index(0-15)
// 查看db大小
DBSIZE
// 查看当前数据库所有key
key *
// 清除当前数据库
flushdb
// 清除全部数据库内容
flushall
.// 判断键是否存在
exists key
// 移除key
move key 1(1表示当前库)
// 设置过期时间
expire key time
// 查看过期时间
ttl key
// 值得类型
type key
默认端口6379
单线程
是基于内存操作,cpu不是redis性能瓶颈。redis的瓶颈是根据机器的内存和网络带宽的。
redis是将数据放在内存,多线程(CPU上下文切换:耗时操作),对于内存系统来说,如果没有上下文切换,效率就是最高的,多次读写在一个CPU上的,在内存的情况下,单线程就是最佳方案。
基本数据类型
- String
是简单的key-value类型,value其实不仅可以是String,也可以是数字
应用:微博数,粉丝数// 追加,不存在就相当于setkey append key value(追加的value) // 获取字符串长度 strlen key // 加一 incr key // 减一 decr key // 步长 incr/decr key nums(长度) // 截取字符串 getrange key startIndex endIndex // 替换指定位置开始的字符串 setrange key index string // set with expire 设置过期时间 setex key times // set if not exist 如果不存在,创建(在分布式锁中常使用) setnx key value // 批量创建 mset key1 value1 key2 value2 key3 value3 //批量获取 mget key1 key2 key3 // getset 如果不存在值,则返回nil,并设置新值,如果存在值,则返回值,并设置新值 getset key value
- Hash
是string类型的field和value的映射表,特别适合用于存储对象hset/hmset key field value(设置一个/多个),hget/hmset/hgetall(获取一个/多个/所有), hdel(删除指定的key),hlen(长度),hexists(判断key是否存在),hvals(只获取所有的值), hkeys(只获取所有的key),hincrby,hdecrby,hsetnx(如果存在则不能设置,如果不存在则可以设置)
- List
链表,应用场景非常多,是redis最重要的数据结构之一
redis list 的实现为一个双向链表,既可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销// 存值 lpush(先进后出) lpush key value // 取值 lrange(可以实现分页查询) lrange key startIndex endIndex // rpush 将值放在列表尾部 rpush key value // lpop 移除当前的第一个值 rpop 移除最后一个值 lpop/rpop key // lindex 根据下标获取值 lindex key index // Llen 长度 Llen key // lrem 移除指定值 lrem key num(几个) value // ltrim保留指定长度的值 ltrim key startIndex endIndex // rpoplpush 移除列表最后一个元素,将他移动到新的列表中(对列) // lset 将列表中指定位置的值替换 // linsert 在某个位置插入值 linsert key before/after value newValue
- Set
set中的值是不能重复的 ,对外提供的功能与list相似,特殊之处在与set可以自动排重,set提供了判断某个成员是否在一个set集合内的重要接口,可以实现交集,并集,差集的操作sadd,srem(移除),scard(获取set集合内的元素个数),srandmember(随机抽取元素),smembers(查看所有元素), spop(随机删除元素),smove(将集合中指定的值,移动到另一个集合中),sdiff(不同的,差集),sinter(交集),SUNION(并集)
- Zset
有序集合,在set的基础上增加了权重参数score,使集合中的元素能按score进行有序排列。比如礼物排行榜等。zadd(增加),zrange(展示),zrangebyscore(zrangebyscore salary min max count按权重展示,从小到大), zervrange(从大到小展示),zrem(移除),zcard(获取个数),zcount(获取指定区间的成员数量)
三种特殊类型
- geospatial 地理位置
可以推算地理位置,两地之间的距离,周围的人。底层的实现原理就是Zset,也可以用zset命令来操作geo// 添加地理位置(经<-180,180>、纬<-85,85>、名称) getadd key long lati member // 从指定的key里返回所有给定位置元素的位置(经纬) geopos // 返回两个给定的位置间的距离(可加单位) geodist // 已给定的经纬度为中心,找出某一半径内的元素(中心是经纬) georadius //找出位于指定位置范围的元素,中心点是由给定的位置的元素决定的(中心是元素) georadiusmember //返回一个或多个位置元素的geohash表示(将二位的经纬度转换为一维的hash字符串) geohash
- hyperloglog 数据结构
基数:不重复的元素,可以接受误差
做基数统计的算法 ,优点:占用内存是固定的,2^64不同的元素的技术,只需要废12kb内存,如果从内存角度来说,是首选// 增加 PFadd // 个数 PFcount // 合并(并集) PFmerge
- bigmaps 位图,数据结构
位存储,用途:签到bitcount(统计)
事务
ACID:原子性,一致性,隔离性,持久性。
redis事务没有隔离级别的概念。
所有的命令在事务中,并没有直接执行,只有发起执行命令才会执行
redis单条命令是保存原子性的,但事务不保证原子性
事务:
- 开启事务(multi)
- 命令入队
- 执行事务(exec)取消事务(discard)
事务中所有命令都会序列化、按顺序执行,事务在执行过程中,不会被其他客户端发来的命令请求所打断的
运行时异常:其他命令会正常执行,错误命令会抛出异常
监控
乐观锁:更新数据的时候去判断一下,在此期间是否有人修改过数据
获取version
更新的时候比较version
watch key(监视,可做乐观锁) ,unwatch(关闭监视,放锁)
Jedis
redis,java连接开发工具
// 创建连接
Jedis jedis = new Jedis("127.0.0.1",6379);
// 测试是否连接
System.out.println(jedis.ping());
//开启监听
String watch = jedis.watch("a");
// 事务
Transaction multi = jedis.multi();
try {
//执行事务
multi.exec();
}catch (Exception e){
// 放弃事务
multi.discard();
}
// 关闭监听
jedis.unwatch();
//关闭连接
jedis.close();