缓存数据库redis
什么是Redis?
Redis是一个TCP服务器,支持请求/响应协议。 在Redis中,请求通过以下步骤完成:
- 客户端向服务器发送查询,并从套接字读取,通常以阻塞的方式,用于服务器响应。
- 服务器处理命令并将响应发送回客户端。
Redis是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库,缓存和消息中间件。它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
那么问题来了,既然我们要说的是缓存数据库redis,而只是了解了redis,那么什么又是缓存数据库,Redis和缓存数据库又是什么关系?
缓存数据库
NoSQL(nosql = not only SQL),意为不仅仅是数据库。
NoSQL,泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系型数据库应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模集合多重数据种类带来的挑战,尤其是大数据应用难题。
所以如果有人说NoSQL就是Redis,那么就大错特错,Redis只是NoSQL四大类中的一种。
NoSQL数据库的四大分类
键值(Key-Value)存储数据库
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。[3] 举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.
列存储数据库。
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。[2] 如:Neo4J, InfoGrid, Infinite Graph.
因此,我们总结NoSQL数据库在以下的这几种情况下比较适用:
- 1、数据模型比较简单;
- 2、需要灵活性更强的IT系统;
- 3、对数据库性能要求较高;
- 4、不需要高度的数据一致性;
- 5、对于给定key,比较容易映射复杂值的环境。
分类 | Examples举例 | 典型应用场景 | 数据模型 | 优点 | 缺点 |
键值 (key-value) |
Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB |
内容缓存, 主要用于处理大量数据的高访问负载, 也用于一些日志系统等等。 |
Key 指向 Value 的键值对,通常用 hash table来实现 |
查找速度快 |
数据无结构化, 通常只被当作字 符串或者二进制 数据 |
列存储数据库 |
Cassandra, HBase, Riak |
分布式的文件系统 |
以列簇式存储, 将同一列数据存在 一起 |
查找速度快, 可扩展性强, 更容易进行 分布式扩展 |
功能相对局限 |
文档型数据库 |
CouchDB,MongoDb |
Web应用(与Key-Value类似, Value是结构化的,不同的是数 据库能够了解Value的内容) |
Key-Value对应 的键值对,Value 为结构化数据 |
数据结构要求 不严格,表结构 可变,不需要像 关系型数据库一 样要预先定义表 结构 |
查询性能不高, 而且缺乏统一 的查询语法。 |
图形(Graph) 数据库 |
Neo4J, InfoGrid, Infinite Graph |
社交网络,推荐系统等。 专注于构建关系图谱 |
图结构 |
利用图结构相关算 法。比如最短路径 寻址,N度关系查 找等 |
很多时候需要对整 个图做计算才能得 出需要的信息,而 且这种结构不太好 做分布式的集群方 案。 |
适用场景
- 1、数据模型比较简单;
- 2、需要灵活性更强的IT系统;
- 3、对数据库性能要求较高;
- 4、不需要高度的数据一致性;
- 5、对于给定key,比较容易映射复杂值的环境。
Redis
redis是业界主流的key-value nosql 数据库之一。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
优点
- 异常快速 : Redis是非常快的,每秒可以执行大约110000设置操作,81000个/每秒的读取操作。
- 支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。
- 这使得在应用中很容易解决的各种问题,因为我们知道哪些问题处理使用哪种数据类型更好解决。
- 操作都是原子的 : 所有 Redis 的操作都是原子,从而确保当两个客户同时访问 Redis 服务器得到的是更新后的值(最新值)。
- MultiUtility工具:Redis是一个多功能实用工具,可以在很多如:缓存,消息传递队列中使用(Redis原生支持发布/订阅),在应用程序中,如:Web应用程序会话,网站页面点击数等任何短暂的数据。
使用前,需要对其环境安装配置
在Ubuntu下,只需要输入apt-get install redis-server即可。安装完成后,redis-server启动服务,然后redis-cli就能对其进行操作了。
我们可以对其设置密码,以保证其安全性 进入 vi /etc/redis.conf下改为 requirepass '密码' 即可.
远程链接时redis-cli -h 127.0.0.1 -p 6379 -a "mypassword"
在python环境下,需要 pip install redis
如果在python上链接不上则需要修好配置文件的下的bind,进入 vi /etc/redis.conf下改为 bind 0.0.0.0 即可。
连接方式,没有密码时,则不用填写password
import redis
r = redis.Redis(host='10.211.55.4', port=6379,password='mypassword')
Redis的常用操作
String
redis中的String在在内存中按照一个name对应一个value来存储
查看set 命令什么用法
get(name): 获取值
mget(keys, *args)
批量获取
如:
mget('ylr', 'wupeiqi')
或
r.mget(['ylr', 'wupeiqi'])
127.0.0.1:6379> help set SET key value [EX seconds] [PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
在Redis中设置值,默认,不存在则创建,存在则修改
参数:
ex,过期时间(秒)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行
xx,如果设置为True,则只有name存在时,岗前set操作才执行
setnx(name, value)
设置值,只有name不存在时,执行设置操作(添加)
setex(name, time,value)
# 设置值
# 参数:# time,过期时间(数字秒 或 timedelta对象)
psetex(name, time_ms, value)
# 设置值
# 参数:# time_ms,过期时间(数字毫秒 或 timedelta对象)
mset(*args, **kwargs)
批量设置值
如:
mset(k1='v1', k2='v2')
或
mget({'k1': 'v1', 'k2': 'v2'})
getset(name, value)
设置新值并获取原来的值
getrange(key, start, end)
# 获取子序列(根据字节获取,非字符)
# 一个汉子3个字节
setrange(name, offset, value)
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
# 参数:
# offset,字符串的索引,字节(一个汉字三个字节)
# value,要设置的值
setbit(name, offset, value)
# 对name对应值的二进制表示的位进行操作 # 参数:
# name,redis的name
# offset,位的索引(将值变换成二进制后再进行索引)
# value,值只能是 1 或 0
getbit(name, offset)
# 获取name对应的值的二进制表示中的某位的值 (0或1)
bitcount(key, start=None, end=None)
# 获取name对应的值的二进制表示中 1 的个数
# 参数:
# key,Redis的name
# start,位起始位置
# end,位结束位置
strlen(name)
# 返回name对应值的字节长度(一个汉字3个字节)
incr(self, name, amount=1)
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 # 参数:
# name,Redis的name
# amount,自增数(必须是整数) # 注:同incrby
decr(self, name, amount=1) : 自减
incrbyfloat(self, name, amount=1.0)
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 # 参数:
# name,Redis的name
# amount,自增数(浮点型)
append(key, value)
# 在redis name对应的值后面追加内容 # 参数:
key, redis的name
value, 要追加的字符串
Hash操作
hash表现形式上有些像pyhton中的dict,可以存储一组关联性较强的数据,在Redis中,每个哈希(散列)可以存多达4亿个键值对
hscan(name, cursor=0, match=None, count=None)
# 增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆 # 参数:
# name,redis的name
# cursor,游标(基于游标分批取获取数据)
# match,匹配指定key,默认None 表示所有的key
# count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数 # 如:
# 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
# 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
# ...
# 直到返回值cursor的值为0时,表示数据已经通过分片获取完毕
hscan_iter(name, match=None, count=None)
# 利用yield封装hscan创建生成器,实现分批去redis中获取数据 # 参数:
# match,匹配指定key,默认None 表示所有的key
# count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
常用的命令如下
命令 | 解释 |
HDEL key field2 [field2] | 删除一个或多个哈希字段。 |
HEXISTS key field | 判断是否存在散列字段。 |
HGET key field | 获取存储在指定键的哈希字段的值。 |
HGETALL key | 获取存储在指定键的哈希中的所有字段和值 |
HINCRBY key field increment | 将哈希字段的整数值按给定数字增加 |
HINCRBYFLOAT key field increment | 将哈希字段的浮点值按给定数值增加 |
HKEYS key | 获取哈希中的所有字段 |
HLEN key | 获取散列中的字段数量 |
HMGET key field1 [field2] | 获取所有给定哈希字段的值 |
HMSET key field1 value1 [field2 value2 ] | 为多个哈希字段分别设置它们的值 |
HSET key field value | 设置散列字段的字符串值 |
HSETNX key field value | 仅当字段不存在时,才设置散列字段的值 |
HVALS key | 获取哈希中的所有值 |
List
List操作,redis中的List在在内存中按照一个name对应一个List来存储
lpush(name,values)
# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边 # 如:
# r.lpush('oo', 11,22,33)
# 保存顺序为: 33,22,11 # 扩展:
# rpush(name, values) 表示从右向左操作
其余命令详情列表如下
命令 | 解释 |
BLPOP key1 [key2 ] timeout | 删除并获取列表中的第一个元素,或阻塞,直到有一个元素可用 |
BRPOP key1 [key2 ] timeout | 删除并获取列表中的最后一个元素,或阻塞,直到有一个元素可用 |
BRPOPLPUSH source destination timeout | 从列表中弹出值,将其推送到另一个列表并返回它; 或阻塞,直到一个可用 |
LINDEX key index | 通过其索引从列表获取元素 |
LINSERT key BEFORE/AFTER pivot value | 在列表中的另一个元素之前或之后插入元素 |
LLEN key | 获取列表的长度 |
LPOP key | 删除并获取列表中的第一个元素 |
LPUSH key value1 [value2] | 将一个或多个值添加到列表 |
LPUSHX key value | 仅当列表存在时,才向列表添加值 |
LRANGE key start stop | 从列表中获取一系列元素 |
LREM key count value | 从列表中删除元素 |
LSET key index value | 通过索引在列表中设置元素的值 |
LTRIM key start stop | 修剪列表的指定范围 |
RPOP key | 删除并获取列表中的最后一个元素 |
RPOPLPUSH source destination | 删除列表中的最后一个元素,将其附加到另一个列表并返回 |
RPUSH key value1 [value2] | 将一个或多个值附加到列表 |
RPUSHX key value | 仅当列表存在时才将值附加到列表 |
Set集合
就是不允许重复的列表
sadd(name,values)
# name对应的集合中添加元素
scard(name)
获取name对应的集合中元素个数
sdiff(keys, *args)
在第一个name对应的集合中且不在其他name对应的集合的元素集合
sdiffstore(dest, keys, *args)
获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中
sinter(keys, *args)
获取多一个name对应集合的并集
sinterstore(dest, keys, *args)
获取多一个name对应集合的并集,再讲其加入到dest对应的集合中
sismember(name, value)
检查value是否是name对应的集合的成员
smembers(name)
获取name对应的集合的所有成员
smove(src, dst, value)
将某个成员从一个集合中移动到另外一个集合
spop(name)
从集合的右侧(尾部)移除一个成员,并将其返回
srandmember(name, numbers)
从name对应的集合中随机获取 numbers 个元素
srem(name, values)
在name对应的集合中删除某些值
sunion(keys, *args)
获取多一个name对应的集合的并集
sunionstore(dest,keys, *args)
获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中
sscan(name, cursor=0, match=None, count=None)
递增地迭代集合中的元素
sscan_iter(name, match=None, count=None)
同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd(name, *args, **kwargs)
# 在name对应的有序集合中添加元素
# 如:
# zadd('zz', 'n1', 1, 'n2', 2)
# 或
# zadd('zz', n1=11, n2=22)
zrank(name, value)
获取某个值在 name对应的有序集合中的排行(从 0 开始)
# 更多:
# zrevrank(name, value),从大到小排序
其余大致和无序集合用法相同。
其它常用操作
delete(*names)
根据删除redis中的任意数据类型
exists(name)
检测redis的name是否存在
keys(pattern='*')
根据模型获取redis的name
更多:
# KEYS * 匹配数据库中所有 key 。
# KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
# KEYS h*llo 匹配 hllo 和 heeeeello 等。
# KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
expire(name ,time)
为某个redis的某个name设置超时时间
rename(src, newsrc)
对redis的name重命名为
move(name, db))
将redis的某个值移动到指定的db下
randomkey()
随机获取一个redis的name(不删除)
type(name)
获取name对应值的类型
Redis管道
管道的基本含义是,客户端可以想服务端发送多个请求,而不必等待回复,并最终在一个步骤中等待回复。
在python中管道的用法如下
由于edis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379) r = redis.Redis(connection_pool=pool) # pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True) pipe.set('name', 'aa')
pipe.set('role', 'bb') pipe.execute()
管道的好处
大大的提高的协议性能,通过管道从连接到本地主机速度增加5倍,英特网的连接至少快100倍。
Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 发布订阅(pub/sub)实现了消息系统,发送者(在redis术语中称为发布者)在接收者(订阅者)接收消息时发送消息。传送消息的链路称为信道。
在python中实现代码如下
from monitor.RedisHelper import RedisHelper obj = RedisHelper()
obj.public('hello')
发布者
from monitor.RedisHelper import RedisHelper obj = RedisHelper()
redis_sub = obj.subscribe() while True:
msg= redis_sub.parse_response()
print msg
订阅者
缓存数据库redis的更多相关文章
- 缓存数据库-redis数据类型和操作(list)
转: 狼来的日子里! 奋发博取 缓存数据库-redis数据类型和操作(list) 一:Redis 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素导列表的头部( ...
- 缓存数据库-redis安装和配置
一:redis安装 python操作redis分为两部分,一为安装redis程序 二是安装支持python操作redis的模块 1)安装redis redis 官方网站:http://www.redi ...
- 缓存数据库-redis介绍
一:Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的 ...
- 三个缓存数据库Redis、Memcache、MongoDB
>>Memcached Memcached的优点:Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key.value的字节大小以及服务器硬件性能,日常环境 ...
- python【第十一篇】消息队列RabbitMQ、缓存数据库Redis
大纲 1.RabbitMQ 2.Redis 1.RabbitMQ消息队列 1.1 RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议 ...
- 消息队列RabbitMQ、缓存数据库Redis
1.RabbitMQ消息队列 1.1 RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中 ...
- 缓存数据库-redis(订阅发布)
一:Redis 发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图展示了频道 c ...
- 缓存数据库-redis(管道)
一:Redis 管道技术 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务.这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听Socket返回,通常 ...
- 缓存数据库-redis数据类型和操作(sorted set)
一:Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是 ...
随机推荐
- 剑指offer--36.整数中1出现的次数(从1到n整数中1出现的次数)
暴力挨个数 ---------------------------------------------------------------------- 时间限制:1秒 空间限制:32768K 热度指 ...
- laravel发送邮件
这里已163为例: 1..env文件配置和mail.php配置(默认使用.env) MAIL_DRIVER=smtp MAIL_HOST=smtp.163.com MAIL_PORT=465 MAIL ...
- 【PL/SQL编程】注释说明
1. 单行注释 由两个连接字符“--”开始,后面紧跟着注释内容. 2. 多行注释 由/*开头, 由*/结尾.
- POJ1797 Heavy Transportation
解题思路:典型的Kruskal,不能用floyed(会超时),上代码: #include<cstdio> #include<cstring> #include<algor ...
- Block Towers (思维实现)
个人心得:这题没怎么看,题意难懂.后面比完再看的时候发现很好做但是怎么卡时间是个问题. 题意:就是有m个可以用2层积木的,n个可以用三层积木的,但是他们不允许重复所以可以无限添加. 比如 3 2 一开 ...
- GlassFish的安装与使用(Windows)
前言 Glassfish是一款由Sun公司开发的(现由甲骨文公司赞助)开源的免费的应用服务器,它既是EJB容器也是WEB容器.Glassfish支持最新版的Java EE标准. Glassfish与T ...
- LOJ10034 图书管理
题意 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想要借书的客人快速查找他们是否有他们所需要的书),我们需要设计一个图书查找系统. 该系统需要支 ...
- C语言词法分析:C#源码
今天继续研究代码解析的算法 这个是算法流程图 有图解可能更直观一点: 以下是c#源码: 1using System; 2using System.IO; 3using System.Tex ...
- linux基础命令复习
1.ls 查看文件和文件夹 1).ls -a 查看文件和文件夹,包括隐藏的 2).ls -l 查看文件和文件夹详情 3).ls -lh 查看文件和文件夹详情,自动生成文件大小单位 4).ls ...
- Flyway客户端使用
一.flyway介绍 Flyway是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式.Flyway可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要 ...