Linux下redis安装、配置、操作
sudo apt update
sudo apt-get install redis-server
nosql介绍
nosql:一类新出现的数据库(not only sql)
特点:
- 不支持sql语法
- 存储结构跟传统关系型数据库中的那种关系表完全不能,nosql中存储的数据都是key、value形式
- nosql的世界中没有一种通用的语言,每种nosql数据库都有自己的api和语法,以及擅长的业务场景
- nosql产品:
- Mongodb
- Redis
- Hbase hadoop
nosql和sql数据库的比较:
- 适用场景不同:sql数据库适合用于关系特别复杂的数据查询场景,nosql反之
- ”事务“特性的支持,sql对事务的支持非常完善,而nosql基本不支持事务
- 两者在不断的取长补短,呈现融合趋势
Redis简介
- Redis是一个开源的使用C语言编写,支持网络,可基于内存亦可持久化的日志型、key-value数据库,并提供多种语言的API,从2010年3月15日起,Redis的开发工作由VMware主持,从2013年5月开始,Redis的开发由Pivotal赞助
- Redis是NoSQL技术阵营中的一员,它通过多种键值数据类型来适应不同的场景下的存储需求,借助一些高层级的接口使用可以胜任如缓存、队列系统的不同角色
Redis特性
- Redis的三大特点:
- 支持数据持久化,可以将内存中数据保存在磁盘中,重启的时候可以再次加载进行使用
- 不仅仅支持简单的key-value类型的数据,同时还提供list、set、zset、hash等数据结构的存储
- 支持数据的备份,即master-slave模式的数据备份
Redis优势
- 性能极高 --Redis读的速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型–Redis支持二进制案例的strings、lists、hashes、sets及ordered sets数据类型操作
- 原子–Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行
- 丰富的特性–Redis还支持Publish/subscribe,通知,key过期等等特性
Redis应用场景
-
**用来做缓存 **
-
可以在某些特定应用场景下替代传统数据库(社交类应用)
-
在一些大型系统中,巧妙地实现一些特定的功能:session共享、购物车等
CentOS7下redis安装
redis 5.0.3 下载地址:http://download.redis.io/releases/redis-5.0.3.tar.gz
一、安装redis
# 下载redis
wget http://download.redis.io/releases/redis-5.0.3.tar.gz
# 解压redis
tar -zxvf redis-5.0.3.tar.gz
# 把解压出来的redis移动到/usr/local/redis文件夹下
mv /root/redis-5.0.3 /usr/local/redis
# 编译安装redis
cd /usr/local/redis
make
make test
make install
二、配置redis
# 用vi编辑redis.conf
vi /usr/local/redis/redis.conf
# 绑定IP,如果需要远程访问,请绑定真实IP
bind 192.168.8.88
# 端口,默认为6379
port 6379
# 是否以守护进程运行(默认为no,改为yes)
daemonize yes
# 数据文件
dbfilename dump.rdb
# 数据文件存储路径
dir /var/lib/redis
# 日志文件
logfile /var/log/redis/redis-server.log
# 数据库,默认有16个
database 16
# 主从复制,类似双机备份
slaveof
启动redis
# 启动redis
redis-server /usr/local/redis/redis.conf # 以哪一个配置文件启动redis
# 结束redis
service redis stop # 结束
netstat -atunp # 查看redis的pid
kill -9 pid
# 客户端连接
redis-cli # 默认连接
redis-cli -h 192.168.8.88 -p 6379 # 指定IP端口连接redis
# 默认连接0号数据库,切换数据库(0-15)
select 数据库号(0-15)
django设置redis缓存
# pip install django-redis
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://your_host_ip:6379',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "yoursecret",
},
},
}
# 测试 python manage.py shell
from django.core.cache import cache #引入缓存模块
cache.set('v', '555', 60*60) #写入key为v,值为555的缓存,有效期30分钟
cache.has_key('v') #判断key为v是否存在
cache.get('v') #获取key为v的缓存
数据结构
redis是key-value的数据结构,每一条数据都是一个键值对
键的类型是字符串
注意:键不能重复
值的类型为分五种:
- string类型
- hash哈希
- list列表 (存储的数据类型为字符串,不可以有其他)
- set 集合 (不可重复)
- zset有序集合
数据的操作行为
- 保存、修改、删除、查询
string 类型
字符串类型是Redis中最为基础的数据存储类型,它在redis中是二进制安全的,这便意味着该类型可以接受 任何格式的数据,如果jpeg图像数据或者json对象描述信息等,在redis中字符串类型的value最多可以容纳的数据长度为512M.
保存
增加单个键值对
# 如果设置的键不存在则为添加,如果设置的键已经存在则修改
# 设置
set key value
# 例1:设置键name,值为"zhangsan"的数据
set name zhangsan
增加有过期时间的键值对
# 设置键值及过期时间,以秒为单位
setex key seconds value
# 例2:设置键a1值abc,过期时间为1分钟
setex a1 60 abc
# 有效期内的键,可以获取到值,过期以后的键,显示值为nil
增加多个键值对
# 设置多个键值
mset key1 value1 key2 value2 ....
# 例3:
mset b1 aa b2 bb b3 cc
追加值
# 用append追加值
append key value
# 例4:往b1对应的值后面追加cc
append b1 cc
获取
单个获取
# 单个获取
get key
# 例:
get name
获取多个
# 获取多个
mget key1 key2
# 例:
mget b1 b2 b3
键命令(通用命令)
查找键,支持正则表达式
keys pattern
查找所有键
keys *
查找键包含b的
keys b*
查找键是否存在,存在返回1,不存在返回0
exists key
查看键对应的值的类型
type key
删除键及对应的值
del key1 key2 ...
设置过期时间
expire key seconds
查看有效时间
ttl key
有效时间以内的为正数,过期的为负数
哈希 hash
hash类型
- hash用于存储对象,对象的结构为属性、值
- 值的类型为string
增加
设置单个属性
hset key field value
例1 :设置user的属性name为zhangsan
hset user name zhangsan
报错提示
redis被配置为保存数据库快照,但它目前不能持久化到硬盘,用来修改集合数据的命令不能用
原因:
强制关闭redis快照导致不能持久化
解决方案:
运行 config set stop-writes-on-bgsave-error no 命令后,关闭stop-wtries-on-bgsave-error解决问题
设置多个属性
# 设置多个属性
hmset key field1 value1 field2 value2 ...
例2:设置user2,name为lisi,age为20
hmset user2 name lisi age 20
获取
获取指定键所有的属性
# 获取指定键所有的属性
hkeys key
获取一个属性的值
# 获取一个属性的值
hget key field
获取多个属性的值
# 获取多个属性的值
hmget key field1 field2
获取所有属性的值
# 获取所有属性的值
hvals key
删除
删除整个,可以用del
删除单个属性对应
hdel key field1 field2...
list 列表
列表的元素类型为string
按照插入顺序排序
增加
在左侧插入数据
# 在左侧插入数据
lpush key value1 value2...
在右侧插入数据
# 在右侧插入数据
rpush key value1 value2..
在指定位置的前或者后插入新元素
# 在指定位置的前或者后插入新元素
linsert key before or after 现有元素 新元素
获取
获取列表内的元素
# 获取列表内的元素
lrange key start stop
设置指定索引位置的元素值
索引从左侧开始,第一个元素为0
索引可以是负数表示尾部开始计数,如-1表示最后一个元素
# 设置指定索引位置的元素值
lset key index value
删除
删除指定元素
- 将列表中count次出现的值元素移除
- count>0 从头往尾移除
- count<0 从尾往头移除
- count=0 移除所有
lrem key count value
set 类型
- 无序集合
- 元素为string类型
- 元素具有唯一性,不重复
- 说明:对于集合没有修改操作
增加
添加元素
# 添加元素
sadd key member1 member2...
获取
获取集合中所有的元素
# 返回所有的元素
smembers key
删除
删除指定元素
# 删除指定元素
srem key member
zset 类型
- sorted set ,有序集合
- 元素为string类型
- 元素具有唯一性,不重复
- 每个元素都会关联一个double畸形的score,表示权重,通过权重将元素从小到大排序
- 说明:没有修改操作
增加
# 添加
zadd key score1 memeber1 score2 memeber2...
获取
- 返回指定范围内的元素
- start 、 stop为元素的下标索引
- 索引从左侧开始,第一个元素为0
- 索引可以是负数,表示从尾部开始计数
zrange key start stop
返回score值在min和max之间的成员
# 返回score值在min和max之间的成员
zrangebyscore key min max
返回member的score值
zscore key member
删除
删除指定元素
# 删除指定元素
zrem key member1 member2...
删除权重在指定范围内的元素
# 删除权重在指定范围内的元素
zremrangebyscore key min max
redis和python交互
安装redis模块
pip install redis
调用模块
# 引入模块
from redis import StrictRedis
# 大多数使用的是Redis全能类
from redis import Redis
创建StrictRedis对象
# 通过init创建对象,指定参数host(如果是本地,默认为localhost)、port(默认为6379)与db(默认为0)
sr = StrictRedis(host="IP", port=6379, db=0)
# 简写
sr = StrictRedis()
from redis import *
if __name__ == "__main__":
# 创建一个StictRedis对象,链接redis数据库
try:
sr = StrictRedis() # 创建对象
# 添加一个key为name,value为zhangsan
# res = sr.set("name", "zhangsan")
# print(res)
# 获取name的值
# res = sr.get("name")
# print(res)
# 修改name对应的值为lisi
# res = sr.set("name", "lisi")
# print(res)
# 删除
# res = sr.delete("name")
# print(res)
# 删除多个键值
# res = sr.delete("a1", "a2")
# print(res)
# 获取数据库中所有的键
res = sr.keys()
print(res)
except Exception as e:
print(e)
redis实现简易队列
from redis import Redis
class RedisQueue(Redis):
def __init__(self, queue_key='redis_queue', host='localhost', port=6379, db=0, password=None, *args, **kwargs):
super().__init__(host, port, db, password, *args, **kwargs)
self._conn = self
self.queue_key = queue_key
def put(self, *key):
return self._conn.lpush(self.queue_key, *key)
def len(self):
return self._conn.llen(self.queue_key)
def get(self, end=True):
return self.filter_str(self._conn.rpop(self.queue_key) if end else self._conn.lpop(self.queue_key))
def get_for_index(self, index):
return self._conn.lindex(self.queue_key, index)
def __iter__(self):
return iter(self.range())
def __next__(self):
return self.get()
def range(self, start_index=0, end_index=-1):
return self._conn.lrange(self.queue_key, start_index, end_index)
def filter_str(self, string):
if string:
return str(string)[2:-1]
return