无序,无重复(唯一),可以存储最多2^32 - 1 个字符串
增加删除元素
返回操作成功的个数
>SADD key member [member ...] >SREM key member [member ...]
e.g.
127.0.0.1:6379> SADD letters a (integer) 1 127.0.0.1:6379> SADD letters a b c (integer) 2
获得集合中的所有元素
>SMEMBERS key
e.g.
127.0.0.1:6379> SMEMBERS letters 1) "c" 2) "a" 3) "b"
判断元素是否在集合中(复杂度O(1))
>SISMEMBER key member
e.g.
127.0.0.1:6379> SISMEMBER letters a (integer) 1 127.0.0.1:6379> SISMEMBER letters d (integer) 0
集合间运算
# 差集 >SDIFF key [key ...] # 交集 >SINTER key [key ...] # 并集 >SUNION key [key ...]
进行集合运算并将结果存储
>SDIFFSTORE destination_key key [key ...] >SINTERSTORE destination_key key [key ...] >SUNIONSTORE destination_key key [key ...]
获得集合中元素个数
>SCARD key
e.g.
127.0.0.1:6379> SCARD letters (integer) 3
随机获取集合中元素
>SRANDMEMBER key [count] count,正数,获取count个不重复的元素 count, 负数,获取|count|个,可能重复
e.g.
127.0.0.1:6379> SRANDMEMBER letters "b" 127.0.0.1:6379> SRANDMEMBER letters 2 1) "a" 2) "c" 127.0.0.1:6379> SRANDMEMBER letters -2 1) "b" 2) "b"
弹出一个元素
>SPOP key
e.g.
127.0.0.1:6379> SPOP letters "c" 127.0.0.1:6379> SCARD letters (integer) 2
sorted set,集合中每个元素都关联一个分数(不同元素分数可以相同),可以根据分数进行排序(最高/最低N个),进行有序相关的操作(分数可以相同)
有序集合使用散列表和跳跃表实现, 读取复杂度更低, 更耗费内存
按点击量排序,按时间排序等等,时间轴操作
增加元素
>ZADD key score member [score member]
e.g.
127.0.0.1:6379> ZADD scoreboard 89 tom 67 peter 100 david (integer) 3 127.0.0.1:6379> ZADD scoreboard 70 peter (integer) 0
获取元素分数
>ZSCORE key member
e.g.
127.0.0.1:6379> ZSCORE scoreboard peter "70"
获取排名在某个范围内的元素列表
分数相同,按字典序排,中文的话,取决于编码方式
#分数从小到大排,返回索引从 start-stop之间的所有元素,包含两端元素, WITHSCORES同时获得元素分数 >ZRANGE key start stop [WITHSCORES] >ZREVRANGE key start stop [WITHSCORES]
e.g.
127.0.0.1:6379> ZRANGE scoreboard 0 2 1) "peter" 2) "tom" 3) "david" 127.0.0.1:6379> ZRANGE scoreboard 0 2 WITHSCORES 1) "peter" 2) "70" 3) "tom" 4) "89" 5) "david" 6) "100" 127.0.0.1:6379> ZREVRANGE scoreboard 0 2 WITHSCORES 1) "david" 2) "100" 3) "tom" 4) "89" 5) "peter" 6) "70"
获取指定分数范围的元素
>ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
e.g.
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 100 WITHSCORES 1) "tom" 2) "89" 3) "david" 4) "100"
希望不包含端点值
>ZRANGEBYSCORE scoreboard 80 (100 正负无穷大 +inf -inf
e.g.
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 (100 WITHSCORES 1) "tom" 2) "89" 127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 +inf WITHSCORES 1) "tom" 2) "89" 3) "david" 4) "100" 127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 +inf WITHSCORES LIMIT 0 1 1) "tom" 2) "89"
增加某个元素分数
>ZINCRBY key increment member
e.g.
127.0.0.1:6379> ZSCORE scoreboard tom "89" 127.0.0.1:6379> ZINCRBY scoreboard 2 tom "91" 127.0.0.1:6379> ZSCORE scoreboard tom "91"
获得集合中元素数量
>ZCARD key
e.g.
127.0.0.1:6379> ZCARD scoreboard (integer) 3
获得指定分数范围内的元素个数
>ZCOUNT key min max
e.g.
127.0.0.1:6379> ZCOUNT scoreboard 80 100 (integer) 2
删除一个或多个元素
>ZREM key member [member ...]
按照排名范围删除元素
>ZREMRANGEBYRANK key start stop
按照分数范围删除
>ZREMRANGEBYSCORE key min max
获得元素排名
>ZRANK key member #从小到大 >ZREVRANK key member #相反
e.g.
127.0.0.1:6379> ZRANK scoreboard tom (integer) 1
计算有序集合的交集
>ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] #返回值为destination中元素个数 #AGGREGATE sum默认值,destination键中元素分数是每个参与计算的集合中该元素分数的和 min取最小值 max取最大值 #WEIGHTS 设置每个集合的权重,每个集合在参与计算时分数会被乘以权重
Redis中事务是一组命令的集合, 一个事务中的命令要么都执行, 要么都不执行
> MULTI > SADD k1 v1 > SADD k2 v2 > EXEC
注意, 不支持回滚功能
可以对列表/集合/有序集合进行排序
最强大最复杂, 用不好可能成为性能瓶颈 O(n + mlogm) n为排序个数, m为返回个数
>SORT key #从小到大 >SORT key DESC #从大到小
SORTBY
127.0.0.1:6379> LPUSH sortbylist 2 1 3 (integer) 3 127.0.0.1:6379> SET itemscore:1 50 OK 127.0.0.1:6379> SET itemscore:2 100 OK 127.0.0.1:6379> SET itemscore:3 -10 OK 127.0.0.1:6379> SORT sortbylist BY itemscore:* DESC 1) "2" 2) "1" 3) "3"
SORTBY GET
127.0.0.1:6379> SORT sortbylist BY itemscore:* DESC GET POST:*->title GET POST:*->time
SOTRBY GET STORE
127.0.0.1:6379> SORT sortbylist BY itemscore:* DESC GET POST:*->title GET POST:*->time STORE new_key
TTL, time to live
时效数据,过一定时间删除这些数据
#设置 >EXPIRE key seconds 1表示设置成功, 0表键不存在或设置失败 #查询 >TTL key 键不存在返回-1 or 没有设置生存时间 #去除时效 >PERSIST key #SET/GETSET为键赋值会同时清除键的生存时间
一般队列
生产者 LPUSH 消费者 RPOP BRPOP 和RPOP类似,但是当列表中没有元素时,BRPOP会一直阻塞住链接,直到有新元素加入
优先队列
BLPOP key [key ...] timeout,同时检测多个键,如果所有键都没有元素则阻塞,如果其中有一个键有元素,则从该键中弹出元素 如果都有,则从左到右的顺序取第一个键中的一个元素 BLPOP queue:1 queue:2 queue:3 0
进程间消息传递
订阅者:订阅者可以订阅一个或多个频道
>SUBSCRIBE channel1
发布者:可以向指定的频道发送消息,所有订阅此频道的订阅者都会受到此消息
>PUBLISH channel1 helloworld
官方推荐redis-py
安装
sudo pip install redis sudo easy_install redis
使用
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令(比如,SET命令对应与StrictRedis.set方法)Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py>>> import redis>>> r = redis.StrictRedis(host='localhost', port=6379, db=0)>>> r.set('foo', 'bar')True>>> r.get('foo')'bar'
connection pool
管理对一个redis server的所有连接,避免每次建立、释放连接的开销。 默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。 pool = redis.ConnectionPool(host='127.0.0.1', port=6379) r = redis.Redis(connection_pool=pool)
pipeline机制
可以在一次请求中执行多个命令,这样避免了多次的往返时延 当一组命令中每条命令都不依赖于之前的执行结果, 可以使用 pipe = r.pipeline() pipe.set('one', 'first') pipe.set('two', 'second') pipe.execute() pipeline中的操作是原子的,要改变这种方式,可以传入transaction=False pipe = r.pipeline(transaction=False)
什么应用,都用什么方式处理的
1.一般的缓存
用字符串类型足矣, e.g.注册时得用户名冲突,在线用户
>SET key value >GET
一些缓存场景
存储会话缓存(Session Cache), 利用持久化, 保存一些信息, 例如购物车 全页缓存(FPC)
2.计数,访问量统计,自增id等
>INCR key
3.存储对象实例
用散列 >HSET key field value >HGET key field
4.存列表,队列相关
作为队列使用
文章分类列表,评论列表等
用列表 >LPUSH key value >RPUSH key value >LPOP key >RPOP key
5.集合相关的
标签云等
>SADD key member >SREM key member
6.排序相关
排行榜
访问量排序,点击量等
用有序结合 >ZADD key score member
7.访问频率控制
设置key的失效时间 用 INCR 访问时检查次数, 若超过阈值, 走限制逻辑
or 记录次数, 超过阈值, 检查与最早一个相差是不是1分钟, 是, 走限制逻辑, 不是, 现有时间加入列表, 同时删除最早元素
8.发布/订阅
会用到的
重启后数据不丢失, 两种方式, 可单独使用或者结合使用
持久化:
RDB
快照,符合一定条件时,将内存中的所有数据进行快照并存储到硬盘上 快照的条件可以在配置文件中配置, 两个参数: 时间和改动的键的个数 Redis默认采用的持久化方式 过程 1. Redis使用fork函数复制一份当前进程(父进程)的副本(子进程) (存的是fork时刻的数据) 写时复制copy-on-write 开始时父子共享同一内存数据, 当父进程修改某片数据, 操作系统复制一份以保证子进程数据不受影响 2. 父进程继续接收命令, 子进程开始将内存中数据写入硬盘中临时文件 3. 写入结束后, 替换旧的RDB文件 任意时刻rdb文件都是完整地, 可以用于备份 可以手动发SAVE / BGSAVE 让redis执行快照(前者由主进程进行快照操作,阻塞其他请求, 后者fork子进程)
AOF
每次执行一条会修改Redis中数据的命令,Redis会将该命令写到硬盘中的AOF文件 开启, 设置 appendonly yes 默认文件名 appendonly.aof 可以通过appendfilename设置 纯文本文件, 每当达到一定条件时可以进行重写 auto-aof-rewrite-percentage 100 #超过上一次百分比 auto-aof-rewrite-min-size 64mb #允许重写的最小aof文件大小 默认30s, 执行的命令同步到aof 可以配置 appendfsync everysec # 每秒一次
Redis可以配置主从数据库
redis-server --port 6380 --slaveof 127.0.0.1 6379
复制原理: 从数据库启动, 向主库发SYNC, 主库后台开始保存快照(RDB), 并将保存期间的命令缓存起来. 快照完成后, 将快照文件和缓存的命令发送给从库, 从库收到后载入快照文件并执行命令. 不支持断点续传
读写分离: 主库禁用持久化, 从库启用. 从库崩溃, 重启自动更新. 主库崩溃, 从库提升为主库再修复
常用查看命令
telnet连接
>telnet 127.0.0.1 6379
设定最大可用内存
如果服务器内存有限, 大量使用缓存且生存时间设置过长会导致Redis占满内存. or 为了防止占用内存过大而将生存时间设太短导致命中率过低
可以限制redis使用的最大内存, 按照一定规则淘汰不需要的键
配置文件 maxmemory 限制最大可用内存大小(单位字节) maxmemory-policy 超过限制时的删除策略,一直删除直到小于指定内存 volatile-lru 使用LRU算法删除一个键,只对设置了生存时间的 allkeys-lru 使用LRU算法删除一个键 volatile-random 随机,只对设置了生存时间的 allkeys-random volatile-ttl 删除生存时间最近的 noeviction 不删除键,返回错误
耗时命令日志
> SLOWLOG GET
批量删除
#删除 /test/*开始的 ./redis-cli -a password -n 0 keys "/test/*" | xargs ./redis-cli -a password -n 0 del
精简键名和键值, 最直观的减少内存占用的方式
The end! To be continue ....
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0