redis是一个开源的、使用C语言编写、支持网络交互、可持久化的Key-Value数据库
它通常被称为数据结构服务器
Redis的外围由一个键、值映射的字典构成。与其他非关系型数据库主要不同在于:Redis中的值的类型不仅限于字符串,还支持如下抽象数据类型:
Redis通常将全部的数据存储在内存中。2.4版本后可配置为使用虚拟内存,一部分数据集存储在硬盘上,但这个特性废弃了
目前通过两种方式实现持久化:
我们都常听到Redis是用于缓存,缓存也是非常必要的,提高代码的性能。除了Redis 还有一种缓存技术是 使用 Memcached 它出现的比Redis早, 功能也比较单一。
从性能上来说,也就是从缓存的命中率来说 Memcached的性能更好,但和Redis相差不大, 但是Redis所提供的功能更加强大
重要的区别:
缓存命中率:终端用户访问加速节点时, 如果该节点有缓存住了要被访问的数据时就叫命中, 如果没有的话需要回原服务器取,就是没有命中。取数据的过程与用户访问是同步进行的,所以即使是重新取的新数据,用户也不会感觉有延迟。命中率=命中数/(命中数+没有命中数),缓存命中率是判断加速效果好坏的重要因素之一
NoSQL: 比较出名的NoSQL产品 还有 MongoDB,它是基于JSON来存储的,这样就能记录不同的记录字段的长度不同。
NoSQL 指的是 Not only SQL, 也就是不仅仅是SQL,读作N O SQL 而不是NoSQL
它一般用于高并发的读写,这样的情况传统的关系数据库搞不定,并且有高扩展(横向)、高可用的特性。
具体到 Redis 它虽然查询速度快但是结构性不强,并没有什么两全其美的东西。
应用:
缓存、任务队列、排行榜、数据过期处理、分布式集群的 Session 分离
yum isntall redis
安装成功后:
redis-server /etc/redis.conf 运行
下载源码后首先编译 make,为什么编译安装都造,性能好,需要有相应的 gcc 库才可以哦
然后就可以进行安装了:
make PREFIX=/usr/local/redis install
下一步拷贝 conf 配置文件到安装目录就可以了,在配置文件中最好设置为 daemonize yes
这样启动就是后台启动了,启动命令:
redis-server ./redis.conf
可以使用 ps -ef | grep -i redis
来查看是否启动成功。
关闭推荐使用:
redis-cli shutdown
,强制关闭:kill -9 pid
除了使用 cli 自动连接,也可以手动进行连接:redis-cli -h 127.0.0.1 -p 6379
然后可以用 ping 来测试下是否正常,正常情况它会回你一个 pong
Redis 默认有 16 个数据库,以数字命名,从 0 开始,并且是不支持修改的,数量可以在配置文件中设置(database)
使用 SELECT 命令来切换数据库,例如:SELECT 0
数据库直接并不是完全隔离的,也就是说当执行 FLUSHALL
命令时,会清空所有数据库的数据,如果只想清空当前数据库的数据,要执行 FLUSHDB
并且,官方建议不设置数据库的密码,安全应该由服务器来保证(并且也不支持设置单个数据库的密码)
前面说过 Redis 是以键值对存储的,可以想象为一个大 Map,这个命令也就是查询键了!用法如:
KEYS *
查询所有
也可以使用通配符,有四种,? 、 * 、 [] 以及转义符号,至于什么意思,学过正则的都知道哈
判断 key 是否存在,存在返回 1 不存在返回 0 。
可以删除一个或者多个 key,返回的是删除键的个数,键删除了相应的值自然也删除了,删除多个以空格分开
获得键值的数据类型,返回的值可能是 string、hash、list(列表)、set(集合)、zset(有序集合)
帮助命令,就不多说了,教给你命令怎么用,有种用法是:help 空格 [tab]
清空数据库
字符串数据类型是 Redis 最基本的数据类型了,它能存储任何形式的字符串,包括二进制数据;允许存储的数据容量最大 512 MB
存取字符串用的就是 set/get 命令了,还有一个 MGET/MSET 这个命令可以批量读取/设置值(MSET k1 v1 k2 v2)
INCR
是递增命令,并且会返回递增后的值,默认每次递增的是 1,如需特殊指定就是 INCRBY name 2
这样就会每次递增二,如果不存在就会先初始化为 0 然后再递增;
相应的 DECR
就是递减了,比如: DECR id
就是递减 id 这个 key,默认也是每次一,同样也可以指定递减多少,用法和上面一样;
APPEND
是往尾部追加内容,用在这里就是追加字符串内容,比如:APPEND name 233
,返回是的追加后的字符串的长度。
STRLEN
获取字符串的长度,没啥可说的。
还有一个是 getset
先获取值再设置值
其结构可以比作 Python里的 dict
常用的几个命令有:
获取/存储值
hset key name1 value1
hget key name1
# 批量存储/获取
hmset key name1 value1 name2 val2
hmget key name1 name2
其他的一些指令就一起说了吧:
# 获取全面的属性和值
hgetall key
# 删除多个值,删除 key 用 del 哦
hdel key name1 name2
# 递增递减都差不多,举一个栗子,前提是 age 这个值(val)要有,并且是数字类型
hincrby key age 5
# 判断属性是否存在
hexists key name
# 属性的个数
hlen key
# 获取所有的属性名
hkeys key
# 获取所有的值
hvals key
常用的一般就是这些吧
同样它也有两种形式,数组的和链表的;特点和数据结构中的也一致
# 两端添加,一个是左边一个是右边
lpush key a b c # c 就在最左边
rpush key a b c
# 两端弹出
rpop key
lpop key
# 查看list
lrange key start end
例如: lrange key 0 -1 # 左边数,第一个到最后一个
# 查看长度
llen key
# 插入到头部,如果 key 不存在就不插入,不会自动创建
lpushx key a
rpushx key a
# 删除,count 的负号表示方向
lrem key count val
lrem key 2 3 # 删除2个3
lrem key -2 1 # 从后面(负号)删除2个1
lrem key 0 2 # 删除所有的2
# 修改值
lset key 3 v # 在第四个位置修改为 v;从 0 开始数
# 插入
linsert key before b ll # 在 b 的前面插入 ll
linsert key after b ll
# 其他
rpoplpush key1 key2 # 把 key1 的右边弹出,添加到 key2 的左边
push 返回的是长度,pop 返回的是弹出的元素,rpoplpush 这种命令非常适合用于 MQ
相当于无序的 List,并且是唯一的
常用的命令有:
# 添加删除
sadd key a b c
srem key c
# 查看值
smembers key
# 是否存在?存在返回 1,不存在返回 0
sismember key a
# 相差比较,和顺序有关
sdiff key1 key2
# 求交集、并集
sinter k1 k2
sunion k1 k2
# 查看数量
scard key
# 获取一个随机值
srandmember key
# 其他
sdiffstore k1 k2 k3 # k2 和 k3 的交集存到 k1
sunionstore k1 k2 k3 # k2 和 k3 的并集存到 k1
在做并集交集的处理时非常有优势,因为服务器端的聚合效率更高
它存的都是字符串的内容,并且有一个分数与之关联,可用来排序,分数是可重复的,值不可以
# 增加、删除数据(返回插入元素的个数,已有的值分数会被覆盖)
zadd key 10 n1 20 n2
zrem key n1 n2
# 获取分数
zscore key name
# 获取成员的数量
zcard key
# 范围查找
zrange key 0 -1
zrange key 0 -1 withscores # 显示分数
zrevrange key 0 -1 # 从大到小进行排序,默认是从小到大
# 按照范围删除(插入顺序)
zremrangebyrank key 0 4
# 按照分数的范围删除
zremrangebyscore 80 100
# 按照分数排序
zrangebyscore key 0 100
zrangebyscore key 0 100 withscores limit 0 2 # 显示部分数据
# 操作分数
zincrby key 3 name # 给 name 的分数 +3
# 计算区间,80-90 之间有几个
zcount key 80 90
可以用来做热点话题和游戏排名之类的
前面说过,Redis 基本是用来做缓存的,并且它是基于内存的,所以当然有必要设置生存时间了;
设置生存时间(PEXPIRE 可以设置毫秒):
EXPIRE Key seconds
然后可以使用 TTL 来查询,返回的是剩余的生存时间,单位是秒;如果是没有限制返回的是 -1;数据已删除是 -2
清除生存时间(重新设置值也会清除生存时间):
PERSIST key
现在一般有两种,一种是官方的,一种是分片式的,当然是官方的好了,但是由于在 3.0+ 的版本官方才支持,所以在以前都是玩分片式的集群
原理其实就是计算 key 的哈希值来进行存储(到相应的 Redis 数据库),这样就会有一个问题:无法动态的增加、减少服务节点,因为毕竟节点的数量涉及到哈希的计算,其实在读取的时候也会涉及到哈希的计算,要不然它怎么知道去那一台找
需要 3.0 + 的版本哦,并且需要前面的主从复制知识
如果是在一台机器上测试,只需要拷贝不同的配置文件,然后启动的时候到相应的目录指定即可
设置集群主要是在配置文件开启:
# 开启集群
cluster-enabled yes
# 指定集群的配置文件
cluster-config-file "nodes-xxxx.conf"
然后就是使用一个官方提供的 Ruby 脚本,运行下就好了。
分布式的原理为通过插槽的分配确定存储位置,特点有:
一般情况插槽会平均分配到各个 Redis,存储数据的时候根据 key 来计算插槽值(当 key 有闭合的大括号时,大括号中的数据为有效值),然后做相应的存储,这样就需要在使用客户端的时候加一个 -c
的命令,设置为自动跟踪重定向,也就是当插槽值不在当前数据库时自动切换,所以直连一个就可以了
当一半以上的服务器 PING 不通某一个服务器(当一个服务器 PING 不通就将其标记为疑似下线),这个服务器就会被标记为下线,同时插槽出现空档,整个集群被标记为不可用。
解决方案可以和前面的主从联系起来,将每个节点设置为主从架构,这样就能保证高可用和负载均衡。
集群中的节点只能使用 0 号数据库,切换数据库(SELECT)会报错
安装
pip isntall redis
创建连接
import redis
conn = redis.Redis(host='127.0.0.1', port=6379, password='...')
具体的调用和正常Redis调用一致
安装
pip isntall django-redis
配置
settings.py
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100},
"PASSWORD": "...",
}
},
...(这里可以配置多个)
}
# 3.设置redis存储django的session信息
# SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# SESSION_CACHE_ALIAS = "default"
获取连接
conn = get_redis_connection('default')
之后的用法与Redis相同