Redis数据结构简介

来源:互联网 发布:python 数据采集 编辑:程序博客网 时间:2024/06/05 16:27

Redis数据结构简介

一.Redis高并发和快速的原因
1. Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。
2. 再说一下IO,Redis使用的是非阻塞IO,IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。
3. Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。
4. 另外,数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
5. 还有一点,Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

  • 简单动态字符串
    redis没有直接使用C传统的字符串表示,而是建立了简单动态字符串(SDS)的抽象类型,并将其作为Redis的默认字符串表示。
    SDS定义:
    struct sdshdr{
    //记录SDS所保留字符串长度
    int len;
    //记录buf数组中为使用字节的数量
    int free;
    //字节数组,保存字符串
    char buf[];
    }
    SDS示例
    C字符串和SDS之间的区别
    这里写图片描述
  • 双端链表
    Redis中发布订阅、链表键、慢查询、监视器等功能都用到了链表。
    Redis链表的特点:
    1、双端:链表节点都带有prev和next指针,获取某个节点的前置节点和后置节点的时间复杂度为O(1).
    2.无环
    3、代表头指针和表尾指针:使用list结构的len属性对list持有的链表节点进行计数,程序获取链表节点数量的时间复杂度为O(1).
    4.多态:可以保持各自不同类型的值。
  • 字典
    字典,又称符号表、关联数组或者映射,是用来保持键值对的抽象数据结构。
    字典在Redis中应用广泛,如数据库和哈希键是用字典实现的。
    Redis中每个字典有两个hash表,一个平时使用,一个仅在rehash时使用。
    Redis中解决键冲突的方法是:链地址法(类似于hashMap).
    Hash冲突的解决方法:1、开放定址法。1.1、线性补偿探测法 1.2、随机探测 1.3、线性探查法 2、拉链法http://blog.csdn.net/willfcareer/article/details/6687117
  • *跳跃表
    跳跃表:有序的数据结构,通过每个节点中维持多个指向其他节点的指针,达到快速访问的目的。支持平均O(logn),最坏O(n)的查找。
    跳跃表是redis有序结合键的底层实现之一。另外一个用处是集群节点中的内部数据结构。
    这里写图片描述
    这里写图片描述
  • 整数集合
    整数集合:集合键的底层实现之一,当一个集合只包含整数值元素,并且这个结合的元素数量不多时,redis就会使用整数结合作为集合键的底层实现。
    整数集合的底层实现为数组,这个数组以有效、无重复的方式保存结合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。
    整数集合可以进行升级,升级带来操作上的灵活性,同时尽可能的节约了空间,不能降级。
  • 压缩队列
    压缩队列:列表键和哈希键的底层实现之一。当一个列表键包含少量列表项,列表项是小整数或者短字符串,redis使用压缩队列来做这个列表键的底层实现。
    压缩队列是为了节约redis内存而来发的,由一系列的连续内存块组成的顺序结构。一个压缩列表可以包含任意多个节点,每个节点可以包含一个字节数组或者一个整数值。
  • Redis 共有字符串、列表、哈希、集合、有序集合五中类型对象。
    String-字符串
    String 数据结构是简单的 key-value 类型,value 不仅可以是 String,也可以是数字。
    Redis 还提供了下面一些操作:
    1.LEN niushuai:O(1)获取字符串长度
    2.APPEND niushuai redis:往字符串 append 内容,而且采用智能分配内存(每次2倍)
    3.设置和获取字符串的某一段内容
    4.设置及获取字符串的某一位(bit)
    5.批量设置一系列字符串的内容
    6.原子计数器
    7.GETSET 命令的妙用,请于清空旧值的同时设置一个新值,配合原子计数器使用
    **Hash——字典**Redis 的 Hash 结构可以使你像在数据库中 Update 一个属性一样只修改某一项属性值。
    List——列表:List 说白了就是链表(redis 使用双端链表实现的 List)。Redis 还提供了操作 List 中某一段元素的 API,你可以直接查询,删除 List 中某一段的元素。
    Set——集合:Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,可以存储一些集合性的数据。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
    1.共同好友、二度好友
    2.利用唯一性,可以统计访问网站的所有独立 IP
    3.好友推荐的时候,根据 tag 求交集,大于某个 threshold 就可以推荐
    Sorted Set——有序集合和Sets相比,Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,比如一个存储全班同学成绩的 Sorted Sets。
    1.带有权重的元素,比如一个游戏的用户得分排行榜
    2.比较复杂的数据结构,一般用到的场景不算太多

Redis常用命令

1 连接操作命令quit:关闭连接(connection)auth:简单密码认证help cmd: 查看cmd帮助,例如:help quit2 持久化save:将数据同步保存到磁盘bgsave:将数据异步保存到磁盘lastsave:返回上次成功将数据保存到磁盘的Unix时戳shutdown:将数据同步保存到磁盘,然后关闭服务3 远程服务控制info:提供服务器的信息和统计monitor:实时转储收到的请求slaveof:改变复制策略设置config:在运行时配置Redis服务器4 对key操作的命令exists(key):确认一个key是否存在del(key):删除一个keytype(key):返回值的类型keys(pattern):返回满足给定pattern的所有keyrandomkey:随机返回key空间的一个keyrename(oldname, newname):重命名keydbsize:返回当前数据库中key的数目expire:设定一个key的活动时间(s)ttl:获得一个key的活动时间select(index):按索引查询move(key, dbindex):移动当前数据库中的key到dbindex数据库flushdb:删除当前选择数据库中的所有keyflushall:删除所有数据库中的所有key5 Stringset(key, value):给数据库中名称为key的string赋予值valueget(key):返回数据库中名称为key的string的valuegetset(key, value):给名称为key的string赋予上一次的valuemget(key1, key2,…, key N):返回库中多个string的valuesetnx(key, value):添加string,名称为key,值为valuesetex(key, time, value):向库中添加string,设定过期时间timemset(key N, value N):批量设置多个string的值msetnx(key N, value N):如果所有名称为key i的string都不存在incr(key):名称为key的string增1操作incrby(key, integer):名称为key的string增加integerdecr(key):名称为key的string减1操作decrby(key, integer):名称为key的string减少integerappend(key, value):名称为key的string的值附加valuesubstr(key, start, end):返回名称为key的string的value的子串6 Listrpush(key, value):在名称为key的list尾添加一个值为value的元素lpush(key, value):在名称为key的list头添加一个值为value的 元素llen(key):返回名称为key的list的长度lrange(key, start, end):返回名称为key的list中startend之间的元素ltrim(key, start, end):截取名称为key的listlindex(key, index):返回名称为key的list中index位置的元素lset(key, index, value):给名称为key的list中index位置的元素赋值lrem(key, count, value):删除countkey的list中值为value的元素lpop(key):返回并删除名称为key的list中的首元素rpop(key):返回并删除名称为key的list中的尾元素blpop(key1, key2,… key N, timeout):lpop命令的block版本。brpop(key1, key2,… key N, timeout):rpop的block版本。rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部7 Setsadd(key, member):向名称为keyset中添加元素membersrem(key, member) :删除名称为keyset中的元素memberspop(key) :随机返回并删除名称为keyset中一个元素smove(srckey, dstkey, member) :移到集合元素scard(key) :返回名称为keyset的基数sismember(key, member) :member是否是名称为keyset的元素sinter(key1, key2,…key N) :求交集sinterstore(dstkey, (keys)) :求交集并将交集保存到dstkey的集合sunion(key1, (keys)) :求并集sunionstore(dstkey, (keys)) :求并集并将并集保存到dstkey的集合sdiff(key1, (keys)) :求差集sdiffstore(dstkey, (keys)) :求差集并将差集保存到dstkey的集合smembers(key) :返回名称为keyset的所有元素srandmember(key) :随机返回名称为keyset的一个元素8 Hashhset(key, field, value):向名称为key的hash中添加元素fieldhget(key, field):返回名称为key的hash中field对应的valuehmget(key, (fields)):返回名称为key的hash中field i对应的valuehmset(key, (fields)):向名称为key的hash中添加元素fieldhincrby(key, field, integer):将名称为key的hash中field的value增加integerhexists(key, field):名称为key的hash中是否存在键为field的域hdel(key, field):删除名称为key的hash中键为field的域hlen(key):返回名称为key的hash中元素个数hkeys(key):返回名称为key的hash中所有键hvals(key):返回名称为key的hash中所有键对应的valuehgetall(key):返回名称为key的hash中所有的键(field)及其对应的value
原创粉丝点击