您的位置:首页 > 理论基础 > 数据结构算法

Redis学习笔记(一)之数据结构与丰富功能

2018-01-26 15:37 120 查看

一.Redis简介:

    redis底层使用C语言开发,使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务,是基于键值对的数据结构服务器,提供了5种主要的数据结构以及多种丰富的功能.由于其数据都存储在内存之中,所以操作起来速度快,同时为了避免一些物理因素的影响,比如断电/机器故障/内存不足等情况提供了两种持久化方式(RBD和AOF).而且还可以根据用户需求在主从复制功能基础上进行分布式实现.

二.Redis使用场景:

    1.缓存 --可以将一些热数据进行缓存,从而提供系统响应能力,降低后端数据库压力,并且redis提供了键值过期时间设置以及灵活控制最大内存和内存溢出后的淘汰策略.

    2.排行榜系统 --redis提供有列表和有序列表数据结构,合理的使用这些数据结构能够方便的构建属于你自己的排行榜系统.

    3.社交网络 --社交网站中的点赞,用户间的交集/并集/差集等操作.

    4.计数器 --redis本身自带了一些自增函数API,可以根据你自身场景进行包装.

    5.消息系统 --redis提供的丰富功能中就包含有发布和订阅功能.

三.Redis的5种数据类型以及涉及的内部编码(查询内部编码命令:object encoding [key]):

    首先需要明确的是redis是键值对的数据存储,也就是键是字符串,其值可以是String(字符串)/hash(哈希)/list(双端列表)/set(无重复集合)/zset(有序的无重复集合),下面逐一讲述.

    1.String --字符串类型的值可以包含普通字符串,数字,二进制(图片,音频,视频)或者系列化对象,但是值最大不能超过512MB.

    其内部编码有三种:

        int是长整型数字.

        embstr是小于等于39个字节的字符串.

        raw是大于39个字节的字符串,当条件无法满足embstr时会自动转为此编码方式实现.

    2.hash --哈希类型的值它本身又是键值对结构,就比如user,user有五项信息,其每一项的信息又有对应的名称键和值.

    其内部编码有二种:

        ziplist是压缩列表,哈希元素个数小于512个并且所有值都小于64字节时自动使用.

        hashtable是哈希表,当条件无法满足ziplist时会自动转换使用此编码实现,相对于ziplist内存开销更大.

    3.list --双端列表,可以从列表两头进行push(插入)和pop(弹出)操作,可根据索引下标操作.

    其内部编码有二种:

        ziplist是压缩列表,哈希元素个数小于512个并且所有值都小于64字节时自动使用.

        linkedlist是链表,当条件无法满足ziplist时会自动转换使用此编码实现.

        quicklist是ziplist和linkedlist两者优势的结合,是3.2版本提供.

    4.set --是无重复元素的无序集合,不能通过索引下标操作.

    其内部编码有二种:

        intset是整数集合,当集合元素都是整数而且个数小于512使用,从而能减少内存开销.

        hashtable是哈希表,当条件无法满足intset时会自动转换使用此编码实现,相对于intset内存开销更大.

    5.zset --是无重复元素的有序集合,为每一个元素分配一个分数作为权重来进行从小到大的排序,分数是可以重复的.

    其内部编码有二种:

        ziplist是压缩列表,有序集合元素个数小于128个并且所有值都小于64字节时自动使用.从而能减少内存的开销.

        skiplist是跳跃表,当条件无法满足ziplist时会自动转换使用此编码实现.

四.Redis的5中数据结构的基本使用(以jedis为例):

    1.全局操作的命令

             exists(key):确认一个key是否存在

             del(key):删除一个key

             type(key):返回值的类型

             keys(pattern):返回满足给定pattern(表达式)的所有key

             randomkey:随机返回key空间的一个key

             rename(oldname, newname):将key由oldname重命名为newname,若newname存在则删除newname表示的key

       
d19e
     dbsize:返回当前数据库中key的数目

             expire:设定一个key的活动时间(s)

             ttl:获得一个key的活动时间

             select(index):按索引查询

             move(key, dbindex):将当前数据库中的key转移到有dbindex索引的数据库

             flushdb:删除当前选择数据库中的所有key

             flushall:删除所有数据库中的所有key

    2.对String操作的命令

         set(key, value):给数据库中名称为key的string赋予值value

         get(key):返回数据库中名称为key的string的value

         getset(key, value):给名称为key的string赋予上一次的value

         mget(key1, key2,…, key N):返回库中多个string(它们的名称为key1,key2…)的value

         setnx(key, value):如果不存在名称为key的string,则向库中添加string,名称为key,值为value

         setex(key, time, value):向库中添加string(名称为key,值为value)同时,设定过期时间time

         mset(key1, value1, key2, value2,…key N, value N):同时给多个string赋值,名称为key i的string赋值value i

         msetnx(key1, value1, key2, value2,…key N, value N):如果所有名称为key i的string都不存在,则向库中添加string,名称key i赋值为value i

         incr(key):名称为key的string增1操作

         incrby(key, integer):名称为key的string增加integer

         decr(key):名称为key的string减1操作

         decrby(key, integer):名称为key的string减少integer

         append(key, value):名称为key的string的值附加value

         substr(key, start, end):返回名称为key的string的value的子串

    3.对List操作的命令

         rpush(key, value):在名称为key的list尾添加一个值为value的元素

         lpush(key, value):在名称为key的list头添加一个值为value的元素

         llen(key):返回名称为key的list的长度

         lrange(key, start, end):返回名称为key的list中start至end之间的元素(下标从0开始,下同)

         ltrim(key, start, end):截取名称为key的list,保留start至end之间的元素

         lindex(key, index):返回名称为key的list中index位置的元素

         lset(key, index, value):给名称为key的list中index位置的元素赋值为value

         lrem(key, count, value):删除count个名称为key的list中值为value的元素。count为0就删除所有值为value的元素,count>0就从头至尾删除count个值为value的元素,count<0就从尾到头删除|count|个值为value的元素。

         lpop(key):返回并删除名称为key的list中的首元素

         rpop(key):返回并删除名称为key的list中的尾元素

         blpop(key1, key2,… key N, timeout):lpop 命令的block版本。即当timeout为0时,若遇到名称为key i的list不存在或该list为空,则命令结束。如果 timeout>0,则遇到上述情况时,等待timeout秒,如果问题没有解决,则对key i+1开始的list执行pop操作。

         brpop(key1, key2,… key N, timeout):rpop的block版本。参考上一命令。

         rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

    4.对Set操作的命令

         sadd(key, member):向名称为key的set中添加元素member

         srem(key, member) :删除名称为key的set中的元素member

         spop(key) :随机返回并删除名称为key的set中一个元素

         smove(srckey, dstkey, member) :将member元素从名称为srckey的集合移到名称为dstkey的集合

         scard(key) :返回名称为key的set的基数

         sismember(key, member) :测试member是否是名称为key的set的元素

         sinter(key1, key2,…key N) :求交集

         sinterstore(dstkey, key1, key2,…key N) :求交集并将交集保存到dstkey的集合

         sunion(key1, key2,…key N) :求并集

         sunionstore(dstkey, key1, key2,…key N) :求并集并将并集保存到dstkey的集合

         sdiff(key1, key2,…key N) :求差集

         sdiffstore(dstkey, key1, key2,…key N) :求差集并将差集保存到dstkey的集合

         smembers(key) :返回名称为key的set的所有元素

         srandmember(key) :随机返回名称为key的set的一个元素

    5.对zset(sorted set)操作的命令

         zadd(key, score, member):向名称为key的zset中添加元素member,score分数用于排序。如果该元素已经存在,则根据score更新该元素的顺序。

         zrem(key, member) :删除名称为key的zset中的元素member

         zincrby(key, increment, member) :如果在名称为key的zset中已经存在元素member,则该元素的score增加increment;否则向集合中添加该元素,其score的值为increment

         zrank(key, member) :返回名称为key的zset(元素已按score从小到大排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”

         zrevrank(key, member) :返回名称为key的zset(元素已按score从大到小排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”

         zrange(key, start, end):返回名称为key的zset(元素已按score从小到大排序)中的index从start到end的所有元素

         zrevrange(key, start, end):返回名称为key的zset(元素已按score从大到小排序)中的index从start到end的所有元素

         zrangebyscore(key, min, max):返回名称为key的zset中score >= min且score <= max的所有元素

         zcard(key):返回名称为key的zset的基数

         zscore(key, element):返回名称为key的zset中元素element的score

         zremrangebyrank(key, min, max):删除名称为key的zset中rank >= min且rank <= max的所有元素

         zremrangebyscore(key, min, max) :删除名称为key的zset中score >= min且score <= max的所有元素

         zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):对N个zset求并集和交集,并将最后的集合保存在dstkeyN中。对于集合中每一个元素的score,在进行AGGREGATE运算前,都要乘以对于的WEIGHT参数。如果没有提供WEIGHT,默认为1。默认的AGGREGATE是SUM,即结果集合中元素的score是所有集合对应元素进行 SUM运算的值,而MIN和MAX是指,结果集合中元素的score是所有集合对应元素中最小值和最大值。

    6.对Hash操作的命令

         hset(key, field, value):向名称为key的hash中添加元素field<—>value

         hget(key, field):返回名称为key的hash中field对应的value

         hmget(key, field1, …,field N):返回名称为key的hash中field i对应的value

         hmset(key, field1, value1,…,field N, value N):向名称为key的hash中添加元素field i<—>value i

         hincrby(key, field, integer):将名称为key的hash中field的value增加integer

         hexists(key, field):名称为key的hash中是否存在键为field的域

         hdel(key, field):删除名称为key的hash中键为field的域

         hlen(key):返回名称为key的hash中元素个数

         hkeys(key):返回名称为key的hash中所有键

         hvals(key):返回名称为key的hash中所有键对应的value

         hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value

五.Redis除了提供5中数据结构之外还提供了如下这些附加功能:

    1.慢查询分析 --通过慢查询分析可以找到存在问题的命令以便进行优化提供查询性能,慢查询功能需要配置两个参数(预设阀值也就是超过多少毫秒为慢查询slowlog-log-slower-than和存储列表最大记录条数slowlog-max-len).

    注意:

    A.这两个配置并没有指定查询日志存放在哪里,实际上redis是使用一个内存列表来存储慢查询日志的,当slowlog-log-slower-than=0则会记录所有命令,当slowlog-log-slower-than<0对于任何命令都不会记录.

    B.当记录超过列表最大限制时,会执行一种先进先出的策略进行淘汰.在慢查询多的时候可能会造成部分慢查询命令丢失,我们可以定期执行slow get命令将慢查询日志持久化到文件或者其他存储中.

    C.默认只能通过命令slowlog get或者slowlog get [num]指定条数来获取慢查询日志,日志内容有标识ID,发生时间戳,命令耗时,执行的命令和参数,此耗时只是命令执行时间,不包含命令排队以及网络传输时间.

    2.Redis shell --redis提供了redis-cli/redis-server/redis-benchmark等shell工具,每个工具都有强大的shell命令帮助功能.

    3.Pipeline(管道/流水线) --在redis客户端将一组命令进行组装一次性发送给redis服务器,并最后返回一个结果集,从而减少中间的网络交互次数与时间,最明显是在跨机房跨地区上,需要注意的是与redis原生批量命令的不同之处在于pipeline是非原子性操作.

    4.事务与Lua --redis提供简单的事务功能,可以将一组命令放到multi和exec两个命令之间,这之间的命令就会按照原子顺序执行,如果你有multi没有exec那么命令并不会真正的执行,只是暂时保存在redis中,redis对于Lua脚本的支持主要是帮助用户实现定制化的命令以及命令的捆绑.

    5. Bitmaps(位图) --位图实际上是一个可以按位操作的字符串,也可以想象为一个以位为单位的数组,数组每个单元只能存储0和1,位图可以帮助我们实现很多高效的统计.比如大流量网站统计活跃用户.

    6.HyperLogLog(基数算法) --超小内存占用的存储,但是使用如此小空间来估算巨大的数据存在一定的失误率,官网给出的数字是0.8%,所以只有在只计算独立总数并可以容忍错误率的情况下使用.

    7.发布订阅 --消息发布者与消息订阅者不进行直接通信,消息发布者向指定频道发布消息,而订阅了该频道的每个客户端都可以接收到该消息,redis没有对发布的消息进行持久化,所以无法实现消息的堆积和回朔.比如聊天室/公告牌.
    8.GEO(地理位置信息) --GEO的数据类型为zset,通过将地理位置的经纬度信息以及对应的名称进行存储,并且提供了相应的命令用于对存储的经纬度信息进行操作.比如摇一摇/找附近.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐