zoukankan      html  css  js  c++  java
  • Redis 百度百科

      Redis 是一个开源的使用 ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、key-value 数据库,并提供多种语言的 API。从2010年3月15日期,Redis 的开发工作由 VMware 主持。从2013年5月开始,Redis 的开发由 Pivotal赞助。

      Redis 是一个 key-value 存储系统。和 Memcached 类似,它支持存储的 value 类型相对更多,包括 string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和 hash(哈希类型)。这些数据类型都支持 pusu/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 Inidan Ocean territory,即 英属印度洋领地)

      目前,Vmware在资助着 Redis 项目的开发和维护。

      Redis 的作者,叫 Salvatore Sanfilippo,来自意大利的西西里岛,现在居住在卡塔尼亚。目前供职于 Pivotal 公司。他使用的网名是 antirez。

      就DB来说,Redis 成绩已经很惊人了,且不说 Memcached 和 Tokyo Cabinet 之流,就说原版的 Memcached,速度似乎也只能达到这个级别。Redis 根本是使用内存存储,持久化的关键是这三条指令:SAVE、BGSAVE、LASTSAVE...

      当接收到 SAVE 指令的时候,Redis 就会 dump 数据到一个文件里面。

      值得一说的是它的独家功能:存储列表和集合,这是它与 mc 之流相比更有竞争力的地方。

      不介绍 mc 里面已有的东东,只列出特殊的:

      TYPE key ——用来获取某 key 的类型。

      KEYS pattern ——匹配所有符合模式的 key,比如 KEYS * 就列出所有的 key 了,当然,复杂度 O(n)

      RANDOMKEY ——返回随机的一个 key

      RENAME oldkey newkey ——key 也可以改名

      列表操作,精华

      RPUSH key string ——将某个值加入到一个 key 列表末尾。

      LPUSH key string ——将某个值加入到一个 key 列表头部。

      LLEN key ——列表长度。

      LRANGE key start end ——返回列表中某个范围的值,相当于 mysql 里面的分页查询那样。

      LTRIM key start end ——只保留列表中某个范围的值。

      LINDEX key index ——获取列表中特定索引号的值,要注意是 O(n) 复杂度。

      LSET key index value ——设置列表中某个位置的值。

      LPOP key

      RPOP key ——和上面的 LPOP 一样,就是类似栈和队列的那种取头取尾指令,可以当成消息队列来使用了。

      集合操作

      SADD key member ——增加元素。

      SREM key member ——删除元素。

      SCARD key ——返回集合大小。

      SISMEMBER key member ——判断某个值是否在集合中。

      SINTER key1 key2...keyN ——获取多个集合的交集元素。

      SMEMBERS key ——列出集合的所有元素。

      还有 Multiple DB 命令,可以更换 db,数据可以隔离开,默认是存放在 DB 0。

      Redis 的外围由一个键、值映射的字典构成。与其他非关系型数据库主要不同在于:Redis 中值的类型不仅限于字符串,还支持如下抽象数据类型:字符串列表、无序不重复的字符串集合、有序不重复的字符串集合、     键、值都为字符串的哈希列表。

      值的类型决定了值本身支持的操作。Redis 支持不同无序、有序的列表,无序、有序的集合间的交集、并集等高级服务器端原子操作。

      Redis 提供五种数据类型:string、hash、list、set、zset(sorted set)。

      string 是最简单的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value,其上支持的操作与 Memcached 的操作类似。但它的功能更丰富。

      list(双向列表)是一个链表结构,主要功能是 push、pop、获取一个范围的所有值等等。操作中 key 理解为链表的名字。

      dict(hash 表)

      set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中 key 理解为集合的名字。

      dict 中 table 为 dictEntry 指针的数组,数组中每个成员为 hash 值相同元素的单项链表。set 是在 dict 的基础上实现的,指定了 key 的比较函数为 dictEncObjKeyCompare,若 key 相等则不再插入。

      zset(排序 set)是 set 的一个升级版本,它在 set 的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset 会自动重新按新的值调整顺序。可以理解了有两列的 mysql 表,一列存 value,一列存顺序。操作中 key 理解为 zset 的名字。

      zset 利用 dict 维护 key->value 的映射关系,用 zsl(zskiplist)保存 value 的有序关系。 zsl 实际是叉数。

      不稳定的多叉树,每条链上的元素从根节点到叶子节点保持升序排序。

      Redis 使用了两种文件格式:全量数据和增量请求。

      全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载。

      增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行 replay 得到数据,序列化的操作包括 SET、RPUSH、SADD、ZADD。

      Redis 的存储分为内存存储、磁盘存储和 log 文件三部分,配置文件中有三个参数对其进行配置。

      save seconds updates,save 配置,指出在多长时间内,有多少次更新操作,就将数据同步到数据文件。这个可以多个条件配合,比如默认配置文件中的设置,就设置了三个条件。

      appendonly yes/no,appendonly 配置,指出是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 Redis 本身同步数据文件是按上面的 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。

      appendfsync no/always/everysec,appendfsync 配置,no 表示等操作系统进行数据缓存同步到磁盘,always 表示每次更新操作后手动调用 fsync() 将数据写到磁盘, everysec 表示每秒同步一次。

      安装

      获取源码、解压、进入源码目录

      使用 wget 工具等下载:

      wget(百度不让用链接)

      tar xzf redis-1.2.6.tar.gz

      cd redis-1.2.6。

      编译生成可执行文件

      由于 makefile 文件已经写好,我们只需要直接在源码目录执行 make 命令进行编译即可:

      make

      make-test

      sudo make install

      make 命令执行完成后,会在当前目录下生成几个可执行文件,分别是 redis-server、redis-cli、redis-benchmark、redis-stat,它们的作用如下:

      redis-server:Redis 服务器的 daemon 启动程序。

      redis-cli:Redis 命令行操作工具。当然,你也可以用  telnet 根据其纯文本协议来操作。

      redis-benchmark:Redis 性能测试工具,测试 Redis 在你的系统及你的配置下的读写性能。

      redis-stat:Redis 状态检测工具,可以检测 Redis 当前状态参数及延迟状况。

      建立 Redis 目录(非必须)

      这个过程不是必须的,只是为了将 Redis 相关的资源统一管理而进行的操作。

      执行以下命令建立相关目录并拷贝相关文件至目录中:

      sudo -s

      mkdir -p /usr/local/redis/bin

      mkdir -p /usr/local/redis/etc

      mkdir -p /usr/local/redis/var

      cp redis-server redis-cli redis-benchmark redis-stat /usr/local/redis/bin/

      cp redis.conf /usr/local/redis/etc/

      配置参数

      在我们成功安装 Redis 后,我们直接执行 redis-server 即可运行 Redis,此时它是按照默认配置来运行的(默认配置甚至不是后台运行)。我们希望 Redis 按我们的要求运行,则我们需要修改配置文件,Redis 的配置文件就是我们上面第二个 cp  操作的 redis.conf 文件它被我们拷贝到了 /usr/local/redis/etc/ 目录下。修改它就可以配置我们的 server 了。如果修改?下面是 redis.conf 的主要配置参数的意义:

      daemonize:是否以后台 daemon 方式运行。

      pidfile:pid 文件位置。

      port:监听的端口号。

      timeout:请求超时时间。

      loglevel:log 信息级别。

      logfile:log 文件位置。

      database:开启数据库的数量。

      save * *:保存快照的频率,第一个 * 表示多长时间,第二个 * 表示执行多少次写操作。在一定时间内执行一定数量的写操作时,自动保存快照。可设置多个条件。

      rdbcompression:是否使用压缩。

      dbfilename:数据快照文件名(只是文件名,不包括目录)。

      dir:数据快照的保存目录(这个是目录)。

      appendonly:是否开启 appendonlylog,开启的话每次写操作会记录一条 log,这会提高数据抗风险能力,但影响效率。

      appendfsync:appendonlylog 如何同步到磁盘(三个选项,分别是每次写都强制调用 fync、每秒启动一次 fync、不调用 fync 等待系统自己同步)。

    daemonizeyes

    pidfile/usr/local/redis/var/redis.pid

    port6379

    timeout300

    logleveldebug

    logfile/usr/local/redis/var/redis.log

    databases16

    save9001

    save30010

    save6010000

    rdbcompressionyes

    dbfilenamedump.rdb

    dir/usr/local/redis/var/

    appendonlyno

    appendfsyncalways

    glueoutputbufyes

    shareobjectsno

    shareobjectspoolsize1024

    将上面内容写为 redis.conf 保存到 /usr/local/redis/etc/ 目录下

    然后在命令行执行:

    /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

    即可在后台启动 redis 服务,这时你通过

    telnet 127.0.0.16379

    即可连接到你的 redis 服务。

    Redis 常用内存优化手段与参数

    通过我们上面的一些实现上的分析可以看出 redis 实际上的内存管理成本非常高,即占用了过多的内存,作者对这点也非常清楚,所以提供了一系列的参数和手段来控制和节省内存,我们来讨论下。

    首先最重要的一点是不要开启 Redis 的 VM 选项,即虚拟内存功能,这个本来是作为 Redis 存储超出物理内存数据的一种数据在内存与磁盘换入换出的一个持久化策略,但是其内存管理成本也非常的高,并且我们后续会分析此种持久化此略并不程序,所以要关闭 VM 功能,请检查你的 redis.conf 文件中 vm-enabled 为 no 。

    其次最好设置下 redis.conf 中的 maxmemory 选项,该选项是告诉 Redis 当使用了多少物理内存后就开始拒绝后续的写入请求,该参数能很好的保护好你的 Redis 不会因为使用了过多的物理内存而导致 swap,最终暗中影响性能甚至崩溃。

    另外 Redis 为不同数据类型分别提供了一组参数来控制内存使用,我们在前面详细分析过 Redis Hash 是 value 内部为一个 HashMap,如果该 Map 的成员数比较少,则会采用类似一堆线性的紧凑格式来存储该 Map,即省去了大量指针的内存开销,这个参数控制对应在 redis.conf 配置文件中下面 2 项:

    1.hash-max-zipmap-entries 64

    2.hash-max-zipmap-value 512

    3.hash-max-zipmap-entries

    含义是当 value 这个 Map 内部不超过多少个成员时会采用线性紧凑格式存储。默认是 64,即 value 内部有 64 个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的 HashMap。

    has-max-zipmap-value 含义是 当 value 这个 Map  内部的每个成员值长度不超过多少字节就会采用线性紧凑来节省空间。

    以上 2 个条件任意一个条件超过设置值都会转换成真正的 HashMap,也就不会再节省内存了,那么这个值是不是设置的越大越好呢,答案当然是否定的,HashMap 的优势就是查找和操作的时间复杂度都是O(1)的,而放弃 Hash 采用一堆存储则是 O(n)的时间复杂度,如果成员数量很少,则影响不大,否则会严重影响性能,所以要权衡好这个值的设置,总体上还是最根本的时间成本和空间成本上的权衡。

    同样类似的参数

    list-max-ziplist-entries 512

    说明:list 数据类型多少节点以下会采用去指针的紧凑存储格式。

    list-max-ziplist-value 64

    说明:list 数据类型节点值大小小于多少字节会采用紧凑存储格式。

    set-max-intset-entries 512

    说明:set 数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储。

    最后想说的是 Redis 内部实现没有对内存分配方面做过多的优化,在一定程度上会存在内存碎片,不过大多数情况下这个不会成为 Redis 的性能瓶颈,不过如果在 Redis 内部存储的大多数数据是数值型的话,Redis 内部采用了一个 shared integer 的方式来省去分配内存的开销,即在系统启动时先分配一个从 1~n 那么多个数值对象放在一个池子中,如果存储的数据恰好是这个数值范围内的数据,则直接从池子里去除该对象,并通过引用计数的方式来共享,这样在系统存储了大量数值下,也能一定程度上 节省内存并且提高性能,这个参数值 n 的设置需要修改呀U你代码中的一行宏定义 REDIS-SHARED-INTEGERS,该值默认是 10000,可以根据自己的需要进行修改,修改后重新编译就可以了。

    另外 Redis 的 6 种过期策略 Redis 中的默认的过期策略是 volatile-lru。设置方式

    config set maxmemory-policy volatile-lru

    maxmemory-policy 六种方式

    volatile-lru:只对设置了多起时间的 key 进行 LRU (默认值)

    allkeys-lru:是从所有 key 里删除不经常使用的 key

    volatile-random:随机删除即将过期的 key 

    allkeys-random:随机删除

    volatile-ttl:删除即将过期的

    noeviction:永不过期,返回错误

    maxmemory-samples 3 是说每次进行淘汰的时候会随机抽取3个 key 从里面淘汰最不经常使用的(默认选项)

      

  • 相关阅读:
    AES对称加密和解密
    Akka并发编程框架 -概念模型(Akka.net或者Orleans)
    .net经典书籍
    计算机专业经典著作(转载)
    windows创建定时任务执行python脚本
    数据库中为什么不推荐使用外键约束(转载)
    《SQL Server性能调优实战》知识点汇总
    数据库索引知识汇总
    ASP.NET常见异常处理示例
    MVC的HTTP请求处理过程(IIS应用程序池、CLR线程池)
  • 原文地址:https://www.cnblogs.com/wangjp/p/6016605.html
Copyright © 2011-2022 走看看