redis-python

时间:2023-03-09 17:34:57
redis-python

一:缓存数据库介绍

NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。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,比较容易映射复杂值的环境。

NoSQL数据库的四大分类表格分析

分类 Examples举例 典型应用场景 数据模型 优点 缺点
键值(key-value)[3]  Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。[3]  Key 指向 Value 的键值对,通常用hash table来实现[3]  查找速度快 数据无结构化,通常只被当作字符串或者二进制数据[3] 
列存储数据库[3]  Cassandra, HBase, Riak 分布式的文件系统 以列簇式存储,将同一列数据存在一起 查找速度快,可扩展性强,更容易进行分布式扩展 功能相对局限
文档型数据库[3]  CouchDB, MongoDb Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) Key-Value对应的键值对,Value为结构化数据 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 查询性能不高,而且缺乏统一的查询语法。
图形(Graph)数据库[3]  Neo4J, InfoGrid, Infinite Graph 社交网络,推荐系统等。专注于构建关系图谱 图结构 利用图结构相关算法。比如最短路径寻址,N度关系查找等 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。[3] 

二:Redis

第一步:安装redis

wget http://download.redis.io/releases/redis-4.0.11.tar.gz
$ tar xzf redis-4.0.11.tar.gz
$ cd redis-4.0.11
$ make
默认的redis安装目录是在/usr/local/redis/ 第二步:启动redis
1.直接启动
先切换到/usr/local/redis/bin目录下
[root@Nagios-Server redis-4.0.11]# cd /usr/local/redis/bin
启动redis
[root@Nagios-Server bin]# ./redis-server
redis-python

如上图:redis启动成功,但是这种启动方式需要一直打开窗口,不能进行其他操作,不太方便。按 ctrl + c可以关闭窗口

2.以后台进程方式启动redis

(1)修改redis.conf文件

[root@Nagios-Server etc]# pwd
/usr/local/redis/etc

1
daemonize no  

修改为

 
daemonize yes

(2)指定redis.conf启动

[root@Nagios-Server bin]# ./redis-server /usr/local/redis/etc/redis.conf、

(3)启动redis

1、在/etc目录下存在redis目录,里面存在6379.conf文件

2.、/etc/init.d/目录下存在redis启动脚本

3、 service redis start

4.   service redis stop

注:提示/var/run/redis_6379.pid does not exist, process is not running  这说明在run下没有这个文件,我们进入到/var/run下发先真的没有这个文件,但是有redis.pid文件。

我们我们要将/etc/init.d/redis 文件中的redis_${REDISPORT}.pid修改为redis.pid

redis-python

操作

0.1. String操作

redis中的String在在内存中按照一个name对应一个value来存储。如图:

(1)Set name value ex none px none nx xx

在Redis中设置值,默认,不存在则创建,存在则修改

参数:

ex,过期时间(秒)

px,过期时间(毫秒)

nx,如果设置为True,则只有name不存在时,当前set操作才执行

xx,如果设置为True,则只有name存在时,当前set操作才执行

例子:

set na ddd

set na mm ex 3  set na mm px 3

set na mm nx   set na mm xx

(2) setnx name value 设置值,只有name不存在时,执行设置操作(添加)

(3) Setex name time value 设置过期时间,单位秒

(4) Psetex name time value 设置过期时间,单位毫秒

(5) mset  mset k1='v1' k2='v2' 批量设置值

(6) getset name value:设置新值并获取原来的值

(7) Strlen name  返回name对应值的字节长度(一个汉字3个字节)

(8) Incr  name  自增加1

(9) Decr name  自减少1

(10) Append name value 在原name后面追加value

1.1 列表

  列表(list)类型是用来存储多个字符串,元素从左到右组成一个有序的集合.列表中的每个字符串被称为元素(element),一个列表最多可以存储(2的32次方)-1个元素.在redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定所有下标的元素等.

  列表类型有两个特点:

    ①列表中的元素是有序的,这就意味着可以通过索引下标获取某个元素或者某个范围内的元素列表.

    ②列表中的元素可以是重复的.

1.1.1 命令

  1) 插入命令

    (1) 从右边插入元素.  rpush key value [value...]

    (2) 从左边插入元素.  lpush key value [value....]  使用方法与rpush一样,从左侧插入.
  

  2) 查询命令

    (1) 查询指定范围内的元素列表  lrange key start end  

    lrange操作会获取列表指定索引范围所有的元素.索引下标有两个特点:第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N.第二,lrange中的end选项包含了自身.

    (2) 获取列表指定索引下的元素  lindex key index

    (3) 获取列表长度  llen key

  3) 删除命令  

    (1) 从列表左侧或右侧弹出元素.  lpop key  rpop key  将列表最左侧与右侧的元素弹出来.

    (2) 删除指定元素  lrem key count value

    lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种:

      count>0,从列表中删除指定数量(count)的元素.

      count<0,从列表中删除count绝对值数量的元素.

      count=0,删除所有.

    (3) 按照索引范围修剪列表  ltrim key start end

  4)修改命令

    修改指定索引下标的元素:  lset key index value

  5) 阻塞操作  

    阻塞式弹出:   blpop key [key...] timeout  brpop key [key...] timeout

    blpop与brpop命令是lpop和rpop命令的阻塞版本,他除了弹出方向不同,使用方法基本相同,所以下面以brpop命令进行说明,

    brpop命令包含两个参数:

    1)列表为空:如果timeout等于3,那么客户端等到三秒后返回,如果timeout=0,那么客户端将一直阻塞,直到弹出成功.

    2)列表不为空:客户端会立刻返回.

  在使用阻塞弹出命令时,有两点需要注意.

  第一点:如果是多个键,那么会从左到右遍历键,一旦有一个键能弹出元素客户端就会立刻返回.
  第二点:如果多个客户端同时对一个键进行操作,那么最先执行命令的客户端可以获取到值.

1.1.2 内部编码

  列表类型的内部编码有两种:  编码名 编码描述

  ziplist(压缩列表)  当列表的元素个数大于list-max-ziplist-entries配置(默认为512个),同时列表中每个元素的长度小于list-max-ziplist-value配置(默认为64字节).

  linkedlist(链表)  当列表的长度或值得大小不满足ziplist的要求,redis会采用linkedlist为列表的内部实现编码.

1.1.3 使用场景

  消息队列:redis的lpush-brpop命令组合即可实现阻塞队列,生产者客户端使用lpush命令向列表插入元素.消费者客户端使用brpop命令阻塞式的"抢"列表中的尾部元素.多个客户端保证消息的负载均衡与可用性.

redis-python

文章列表:每个用户都有属于自己的文章列表.此时可以考虑使用列表,因为列表不但是有序的,同时支持使用lrange按照索引范围获取多个元素.

开发提示:列表的使用场景有很多如: lpush+lpop=Stack(栈)、lpush+rpop=queue(队列)、lpush+brpop=message queue、lpush+ltrim=Capped Collection(有限集合)

1.2 集合  

  集合(set)类型也是用来保存多个的字符串元素,但和列表不同的是:它的元素是无序且不可重复的,不能通过索引获取元素.如下图,集合user:1:follows中包含着"his"、"it"、"sports"、"music"四个元素,一个集合最多可以存储(2的32次方-1)个元素.

redis-python

1.2.1 命令

  1) 集合内操作

    (1) 添加元素  sadd key value [value...]  返回结果为添加成功的元素数量.

    (2) 删除元素  srem key value [value...]  返回结果为删除成功的元素数量.

    (3) 获取元素个数  scard key

    (4) 判断元素是否在集合中  sismember key value

    (5) 随机从集合中返回指定个数元素  srandmember key [count]  [count]是可选参数,如果不写默认为:1.

    (6) 从集合中随机弹出元素  spop key  spop操作可以从集合中随机弹出一个元素.

    (7) 获取集合的所有元素  smembers key  获取集合所有元素,且返回结果是无序的.

  2) 集合间操作

    (1) 求多个集合的交集  sinter key [key...]

    (2) 求多个集合的并集  sunion key [key...]

    (3) 求多个集合的差集  sdiff key [key...]

    (4) 将交集、并集、差集的结果保存.

      sinterstore storeKey key [key...]
      sunionstore storeKey key [key...]
      sdiffstore storeKey key [key...]

    集合间的运算在元素比较多的情况下会比较耗时,所以redis提供了上面三个命令(原命令+store)将集合间交集、并集、差集的结果保存到storeKey中,例如将user:1:follows和user:2:follows两个集合之间的交集结果保存到user:1_2:follows中.

1.2.2 内部编码

  集合类型的内部编码有两种:

  编码名            编码描述

  intset(整数集合)    当集合中的元素全是整数,且长度不超过set-max-intset-entries(默认为512个)时,redis会选用intset作为内部编码.

  hashtable(哈希表)   当集合无法满足intset的条件时,redis会使用hashtable作为内部编码.

1.2.3 使用场景

  集合类型比较典型的使用场景是标签(tag).例如一个用户可能对音乐感兴趣,另一个用户对新闻感兴趣,这些想去点就是标签.有了这些数据就可以获得喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于用户体验来说比较重要.

1.3 有序集合

  有序集合相对于哈希、列表、集合来说会有一点陌生,但既然叫有序集合.那么它和集合必然是有着联系,它保留了集合不能重复元素的特性.但不同的是,有序集合是可排序的.但是他和列表使用索引下标进行排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据.

列表、集合、有序结合的异同点

redis-python

1.3.1 命令

  1)集合内

    (1) 添加成员  zadd key score member [score member ...]

      有关zadd命令有两点需要注意:  Redis 3.2为zadd命令添加了nx、xx、ch、incr四个选项:

        nx:member必须不存在,才可以设置成功,用于添加.

        xx:member必须存在,才可以设置成功,用于添加.

        ch:返回此次操作后,有序结合元素和分数发生变化的个数.

        incr: 对score进行添加操作,相当于后面介绍的zincrby.

      有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间复杂度是O(log(n)),sadd的时间复杂度为O(1).

    (2) 获取成员个数  zcard key

    (3) 获取某个成员的分数  zscore key member

    (4) 获取成员排名  zrank key member  zrevrank key member

    (5) 删除成员  zrem key member [member...]  

    (6) 增加成员分数  zincrby key score member

    (7) 获取制定范围的元素  zrange key start end [withscores]  zrevrange key start end [withscores]

      有序集合是按照分值排名的,zrange是由低到高返回,zrevrange反之,查询全部:zrange user:ranking 0 -1,加上withscores参数显示分数.

    (8) 返回指定分数范围的成员  zrangebyscore key min max [withscores] [limit offset count]  zrevrangebyscore key min max [withscores] [limit offset count]

    (9) 返回指定分数范围成员个数  zcount key min max

    (10) 删除指定排名内的升序元素  zremrangebyrank key start end

    (11) 删除指定分数范围的成员  zremrangebyscore key min max

  2) 集合间的操作

    (1) 交集  zinterstore storeKey keyNum key [key ...] [weights weight [weight...]] [aggregate sum|min|max]  参数说明:

      storeKey:交集计算结果保存到这个键下.

      keyNum:需要做交集的键的个数.

      key[key ...]:需要做交集的键.

      weights weight [weight...]:每个键的权重,在做交集计算时,每个键中的每个member的分值会和这个权重相乘,每个键的权重默认为1.

      aggregate sum|min|sum:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总.默认值为sum.

    (2) 并集  zunionstore storeKey keyNum key [key...] [weights weight [weight...]] [aggregate sum|min|max]  该命令的所有参数和zinterstore是一致的,只不过做的是并集计算.

1.3.2 内部编码

  编码名称        编码描述

  ziplist(压缩列表)    当有序集合的元素小于zset-max-ziplist-entries配置(默认是128个),同时每个元素的值都小于zset-max-ziplist-value(默认是64字节)时,Redis会用ziplist来作为有序集合的内部编码实现,ziplist可以有效的减少内存的使用

  skiplist(跳跃表)      当ziplist的条件不满足时,有序集合将使用skiplist作为内部编码的实现,来解决此时ziplist造成的读写效率下降的问题.

redis-python