Redis的介绍安装以及启动与使用、数据类型、Redis管道、Django使用Redis
一、介绍Redis
1. 详细介绍
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的官网地址,非常好记,是redis.io。(域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地),Vmware在资助着redis项目的开发和维护。
2. 介绍总结
针对以上的小总结:
- redis是缓存数据库
- redis是非关系型数据库,kv键值对存储数据,没有表的概念
- redis是C语言编写的服务,速度非常快
redis为什么速度那么快?
- 纯内存操作所以速度如此之快
- 网络模型使用的IO多路复用所以高并发
- 6.X版本之前都是单进程、单线程架构,没有线程进程间切换因此资源消耗更少
二、安装启动以及运行Redis
1. Redis的安装步骤
首先Mac或Linux系统直接官网源码下载编译安装即可,但是Windows不支持该方法,因此我去这里下载
整个过程非常方便,一直下一步即可完成安装
2. Redis的启动方法
方法一:在cmd终端以此敲以下两个命令即可启动
redis-server # 启动服务端 类似于mysqld命令
redis-cli # 启动客户端 类似于mysql命令
第二种方法:在服务中手动启动redis服务也是可以的
3.图形化界面使用Redis
第一步:下载安装RESP软件(因为安装该软件件几乎没有什么难度因此没有详细介绍步骤)
第二步:与redis数据库链接步骤图解
4.pycharm使用Redis
方法一:普通连接
# 首先下载第三方模块
pip install redis
# 新建脚本py文件
# 第一:步导入模块
from redis import Redis
# 第二步:实例化,连接数据库
conn = Redis(host='127.0.0.1', port=6379)
# 第三步:conn.对象设置数据
conn.set('name','mire')
# 查询数据
res = conn.get('name')
print(res)
# 第四步:最后使用完之后需要关闭连接
conn.close()
设置数据结果
查询数据结果
方法二:连接池连接
那么为什么要使用连接池呢?为了防止咱的项目一下子连接较多的进程导致将项目运行速度变慢,效率降低,导致CPU性能低。
# 新建pool.py文件,写以下代码
import redis
POOL = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379) # 创建一个大小为10的redis连接池
# 在测试文件写以下代码
import redis
from threading import Thread
from pool import POOL
def task():
# 做成模块后,导入,无论导入多少次,导入的都那一个POOL对象
conn = redis.Redis(connection_pool=POOL) # 报错的原因是拿连接,池里不够了,没有等待,线程报错 设置等待,参数
print(conn.get('name'))
for i in range(10):
t = Thread(target=task) # 每次都是一个新的连接,会导致 的连接数过多
t.start()
三、redis五大数据类型
1. 字符串(string)
2. 哈希(字典hash)
3. 列表(list)
4. 集合(set)
5. 有序集合(sort set)
以下的数据类型的操作前提是这个代码
# 第一:导入模块
import redis
# 第二步:产生实例化对象
conn = redis.Redis()
# 第三步:关闭进程
conn.close()
通用操作(五种数据类型都可以用)
delete('key') # 按key值删除,支持一次性删除多个key值
exists('key') # 判断是否存在
keys('*') # 拿出所有的key值
expire('userinfo', 3) # 设置过期时间
rename('name', 'name1') # 重命名
move('name', 8) # 移动
randomkey() # 随机
type('age') # 查看数据类型
1. 字符串及其操作
全部操作
set(name, value, ex=None, px=None, nx=False, xx=False)
setnx(name, value)
setex(name, value, time)
psetex(name, time_ms, value)
mset(*args, **kwargs)
get(name)
mget(keys, *args)
getset(name, value)
getrange(key, start, end)
setrange(name, offset, value)
setbit(name, offset, value)
getbit(name, offset)
bitcount(key, start=None, end=None)
bitop(operation, dest, *keys)
strlen(name)
incr(self, name, amount=1) # incrby
incrbyfloat(self, name, amount=1.0)
decr(self, name, amount=1)
append(key, value)
重点操作
set(name, value, ex=None, px=None, nx=False, xx=False)
"""
ex,过期时间(秒)适合存验证码信息的场景
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行, 值存在,就修改不了,执行没效果
xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
"""
get(name) # 括号里面的参数是key
print(str(conn.get('name'),encoding='utf-8'))
print(conn.get('name'))
strlen(name) # 统计字节长
res=conn.strlen('hobby')
print(res)
incr(self, name, amount=1) # 自增,不会出并发安全问题,单线程架构,并发量高
conn.incr('age')
2. 哈希以及其操作
全部操作
hset(name, key, value)
hmset(name, mapping)
hget(name,key)
hmget(name, keys, *args)
hgetall(name)
hlen(name)
hkeys(name)
hvals(name)
hexists(name, key)
hdel(name,*keys)
hincrby(name, key, amount=1)
hincrbyfloat(name, key, amount=1.0)
hscan(name, cursor=0, match=None, count=None)
hscan_iter(name, match=None, count=None)
重要操作
conn.hset('userinfo', 'name','almira') # 单个设置数据
conn.hset('userinfo', mapping={'name':'阿丽米热', 'age':18}) # 批量设置数据
res=conn.hget('userinfo','name')
print(res)
res = conn.hmget('userinfo', 'name', 'age')
print(res)
res=conn.hgetall('userinfo') # 慎用
print(res)
res=conn.hlen('userinfo')
print(res)
res=conn.hkeys('userinfo')
print(res)
res=conn.hvals('userinfo')
print(res)
res = conn.hexists('userinfo', 'name')
print(res)
res = conn.hdel('userinfo', 'age')
print(res)
3. 列表以及其操作
全部操作
lpush(name, values)
rpush(name, values) 表示从右向左操作
lpushx(name, value)
rpushx(name, value) 表示从右向左操作
llen(name)
linsert(name, where, refvalue, value))
r.lset(name, index, value)
r.lrem(name, value, num)
lpop(name)
rpop(name) 表示从右向左操作
lindex(name, index)
lrange(name, start, end)
ltrim(name, start, end)
rpoplpush(src, dst)
blpop(keys, timeout)
r.brpop(keys, timeout),从右向左获取数据
brpoplpush(src, dst, timeout=0)
重要操作
# 第一个参数是key值,第二个参数是value值且可以传多个value值
conn.lpush('girl', 'mire')
# 指定位置插入数据
conn.linsert('girl', 'after', 'mire', 'llllllll')
# 跟insert的用法一样
conn.lset('girl', 'after', 'mire', 'llllllll')
# 指定位置移除数据,从左侧开始,删除1个
conn.lrem('girls',1,'xxx')
# 从左侧开始删除一条数据,不支持指定位置移除
conn.lpop('girl')
res=conn.lrange('girls',0,0) # 前闭后闭区间
res = str(conn.lindex('girls', 1), encoding='utf-8')
res = conn.llen('girl')
print(res) # 统计出girl列表的所有的value值
# 可以做消息队列使用 阻塞式弹出,如果没有,就阻塞
res=conn.blpop('boys')
print(res)
以下两种数据类型的操作讲解暂时不整理了,等到学习到高级部分时重新整理
4. 集合以及其操作
5. 有序集合及操作
四、Redis管道
1.什么是Redis管道
首先我们思考一下Redis支不支持事务?单实例才支持所谓的事物,支持事务是基于管道的,我对管道的理解是节省资源消耗,还有Redis是纯内存操作因此如果突然断电那么数据不保存,尤其是转账业务,这个就是典型的管道案例。
2.用代码实现管道
"""
conn.decr('zhangsan_jine',100)
conn.incr('lisi_jine',100)
把这两条命令,放到一个管道中(先不执行)
执行excute之后,那两条一次性都执行完成
"""
import redis
conn = redis.Redis()
p=conn.pipeline(transaction=True)
p.multi()
p.decr('zhangsan_je', 100)
p.incr('lisi_je', 100)
p.execute()
conn.close()
五、Django框架中使用Redis
前提是在数据库中有以下键值对
三个方法路由都是通用的
from django.urls import path
from user import views
urlpatterns = [
path('redis_test/',views.test_redis ),
]
方式一:自定义包【通用,不针对框架】
第一步:新建一个pool.py,里面写如下代码
import redis
POOL = redis.ConnectionPool(max_connections=100)
第二步:在views.py中写函数
import redis
from utils.pool import POOL
from django.http import JsonResponse
def test_redis(request):
conn = redis.Redis(connection_pool=POOL)
conn.incr('count')
res = conn.get('count')
return JsonResponse({'count':'当天访问量:%s' % res},json_dumps_params={'ensure_ascii':False})
方式二:django的缓存使用redis【推荐使用】
第一步:下载第三方模块django_redis
pip install django_redis
第二步:在配置文件里面配置如下配置
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}
}
}
}
第三步:在views.py中写视图函数
from django.http import JsonResponse
from django.core.cache import cache
def redis_redis(request):
try:
res = cache.get('count') +1
cache.set('count', res)
except Exception:
cache.set('count',1)
res =1
return JsonResponse({'count':'当天访问量:%s' % res},json_dumps_params={'ensure_ascii':False})
方式三:通过django-redis模块【可扩展性不强】
必须依赖方法二中配置的配置文件
from django.http import JsonResponse
from django_redis import get_redis_connection
def redis_redis(request):
conn = get_redis_connection()
try:
res = int(str(conn.get('count'), encoding='utf-8')) + 1
conn.set('count', res)
except Exception:
conn.set('count', 1)
res = 1
return JsonResponse({'count': '当天访问量:%s' % res}, json_dumps_params={'ensure_ascii': False})
最后展示以下上面代码干了什么?(可以做后台访问量统计的工具,同一个需求用三种方式实现)