记一下一些redis的内容,以免自己忘记。
根据redis的GitHub上的说明:Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。redis默认在6379端口运行
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。在使用方面上来说,redis在缓存数据方面功能十分强大,redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。 Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。但是redis会狂吃你的系统内存,
有鉴于此 redis有一套完整且良好的
缓存清理策略:
- noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令,也就是不清除缓存(即:设置了过期时间且过期时间已经到了或者超过了,缓存也会保留。大部分的写入指令,但DEL和几个例外)
- allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
- volatile-lru: 尝试回收最少使用的键(LRU),但仅限于存在过期时间集合的键(也就是说,设置了过期时间但是还没有过期,如果没有设置过期时间那就不存在回不回收这一问题了),使得新添加的数据有空间存放。
- allkeys-random: 回收随机的键使得新添加的数据有空间存放。
- volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于存在过时间期集合的键(即在设置了过期时间的集合中随机回收删除)。
- volatile-ttl: 回收存在过期时间的集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
这几个清理策略需要结合实际的内存需求进行选择,此处不讲具体业务情况。至于redis的安装也很简单centos,Ubuntu都能在线install 至于windows个人觉得安装没什么意义,没有哪台服务器会用Windows的作缓存服务器吧。。有需要的话可以去:
redis官网 上下载。接下来是关于redis的一些基础
1.关于redis的数据类型:
- String: 字符串
- Hash: 散列
- List: 列表
- Set: 集合
- Sorted Set: 有序集合
首先再次强调一下redis是key-value类型的nosql db。String类型在redis中以二进制安全形式存在,什么意思?这意味着你可以存放任何类型数据只要在redis String的存储大小内(512M)无论是存网页地址,音频文件,视频文件,图片等都是允许的。
对应的操作也有很多很多 ,进入redis: 安装好redis后,命令:redis-cli进入redis:如果有中文乱码的话,请查看下是不是下的32位的?或者 redis-cli --raw进入
关于String
-
- set key value(插入一条key与其对应的value value是字符类型存在)
- DUMP key 序列化给定 key ,并返回被序列化的值。
- DEL key 该命令用于在 key 存在时删除 key。
- EXISTS key 检查给定 key 是否存在。
- EXPIRE key seconds 为给定 key 设置过期时间,以秒计。
- EXPIREAT key timestamp
- EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
- PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。
- TTL key 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
这里有必要说一下关于TTL返回的数据代表的内容:key 不存在时,返回 -2 (早期版本是-2 现在是-1,如果你用的是redis2.8以上的就忽略这个 不会返回-2 不存在或者未设置都是-1); key 存在但是没设置超时时间,返回的是-1 这意味着永不过期,而且:当内存满了以后,找不到能够删除的值时redis会拒绝的所有的写操作,很糟糕的。。。
关于Hash:
- HDEL key field1 [field2] 删除一个或多个哈希表字段
- HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。
- HGETALL key 获取在哈希表中指定 key 的所有字段和值
- HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。
- HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
- HKEYS key 获取所有哈希表中的字段
- HMGET key field1 [field2] 获取所有给定字段的值
- HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。
- HSETNX key field value 只有在字段 field 不存在时设置哈希表字段的值。
- HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。
关于hash:hash是一个string类型的field和value的映射表。hash类型特别适合用于存储对象。在field的数量在限制的范围内以及value的长度小于指定的字节数,那么此时的hash类型是用zipmap存储的,所以会比较节省内存。可以在配置文件里面修改配置项来控制field的数量和value的字节数大小。需要提到的是:这两个配置并不是限制hash结构最多只能存多少个field以及value的最大字节数,而是说在field未超过配置的数量,而且每一个filed对应的value的长度都小于指定的字节数时,注意是两个条件都满足时,该key的存储是采用的zipmap,就是压缩了的数据,节省空间。当field的数量超过了,或者其中有value的长度大于指定的长度,那么整个key就会采用正常的hash结构来在内存中存储。可以考虑用String存储对象的json信息也可以用hash存储序列化的对象信息,具体考虑情况和需求。
hash-max-zipmap-entries 512 #配置字段最多512个
hash-max-zipmap-value 64 #配置value最大为64字节。
必须满足以上两个条件,那么该key会被压缩。否则就是按照正常的hash结构来存储hash类型的key。
根据redis官方说法:每个hash可以存储Every hash can store up to 2^32 - 1 field-value pairs (more than 4 billion).
关于List:
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
- BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
- BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
- LINDEX key index 通过索引获取列表中的元素
- BRPOPLPUSH source destination timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
- LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素
- LLEN key 获取列表长度
- LPOP key 移出并获取列表的第一个元素
- LPUSH key value1 [value2] 将一个或多个值插入到列表头部
- RPOP key 移除列表的最后一个元素,返回值为移除的元素。
- RPUSHX key value 为已存在的列表添加值
- RPUSH key value1 [value2] 在列表中添加一个或多个值
关于List:当PUSH进redis中的list时list会增加长度,由于list也支持存储很大的数据所以,可以存放这样的数据List<T> 当然T也只支持String型,对象的json格式、
关于set:
是string类型数值的无序集合。set元素最大可以包含2的32次方减1个元素。这个插入的时间复杂度稍高 是o(n) (这里需要注意一点 redis2.4版本只支持单个插入 所以时间复杂度是0(1)的 这里指的是之后的版本) list也是o(n) 插n个数据时间复杂度未n,String的是o(1)很明显。。
-
- SADD key member1 [member2] 向集合添加一个或多个成员
- SCARD key 获取集合的成员数
- SDIFF key1 [key2] 返回给定所有集合的差集
- SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中
- SINTER key1 [key2] 返回给定所有集合的交集
- SISMEMBER key member 判断 member 元素是否是集合 key 的成员
- SMEMBERS key 返回集合中的所有成员
- SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合
- SPOP key 移除并返回集合中的一个随机元素
- SREM key member1 [member2] 移除集合中一个或多个成员
- SUNION key1 [key2] 返回所有给定集合的并集
关于set:
我们都知道set中存储的是唯一的数据,故此set常被用于存储一些唯一的内容{比如一个对象于另一个实体的关联比如内容的id字段等,发帖回帖中的评论id等};
关于sorted set:
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。
时间复杂度:O(M*log(N)), N 是有序集的基数, M 为成功添加的新成员的数量。
-
- ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
- ZCARD key 获取有序集合的成员数
- ZCOUNT key min max 计算在有序集合中指定区间分数的成员数 ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment
- ZINTERSTORE destination numkeys key [key ...] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
- ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量
- ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合成指定区间内的成员
- ZREVRANGEBYSCORE key max min [WITHSCORES] 返回有序集中指定分数区间内的成员,分数从高到低排序
- ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
下面是网上的一位老哥说的话,感觉和jdk8中的HashMap有点相似的地方(我指的是思想)。
redis sorted sets里面当items内容大于64的时候同时使用了hash和skiplist两种设计实现。这也会为了排序和查找性能做的优化。所以如上可知:
添加和删除都需要修改skiplist,所以复杂度为O(log(n))。
但是如果仅仅是查找元素的话可以直接使用hash,其复杂度为O(1)
其他的range操作复杂度一般为O(log(n))
当然如果是小于64的时候,因为是采用了ziplist的设计,其时间复杂度为O(n)
关于sorted set:
如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。所以用于存储那种统计后的排行很好。