• dragonfly数据库


      dragonfly数据库这段时间风头正盛,和redis的对飙也颇有看点。可能是刚出现的缘故,网上成型的资料还不多。今天接着这篇博客的机会,了解一下dragonfly。主要内容围绕以下几个主题:
      1.dragonfly基本信息
      2.dragonfly本身的特点
      3.dragonfly和redis对比

    一、dragonfly基本信息

      一句话描述就是:dragonfly是一个的开源内存存储数据库,类型属于nosql,兼容redis和memcached API。
      开源代码(GitHub):GitHub - dragonflydb/dragonfly: A modern replacement for Redis and Memcached
      开源代码(Gitee):DragonflyDB: Dragonfly 是一个现代化的开源内存数据库,兼容 Redis 和 Memcached API (gitee.com)
      官网:Dragonfly (dragonflydb.io)
      代码整体是C和C++组成,具体的语言结构如下:
    在这里插入图片描述
      目前最新的版本是v0.6.0
      dragonfly的使用环境是Linux5.1以上,经本人测试ubuntu的话需要是20.04才能成功运行。不知道为啥,进行源码编译时缺少opt-build这个文件夹中的信息,无奈只能选择二进制文件的运行方式。
      使用步骤如下:

    // 1.首先配置下基础环境:
    sudo apt install ninja-build libunwind-dev libboost-fiber-dev libssl-dev \
         autoconf-archive libtool cmake g++
    // 2.开启服务器端(在dragonfly)
    ./dragonfly-x86_64 --alsologtostderr
    // 3.开启客户端(新起窗口,初次使用需要sudo apt install redis-tools)
    redis-cli
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      然后终端会有输出,服务器端会输出一些相关的配置参数:
    在这里插入图片描述
      关于dragonfly的输入参数,因为文档尚且不完整,所以很难查阅。但dragonfly提供了-help命令,可以看到其参数,下面罗列一下目前所有的可输入参数:

    user@ubuntu:~$ ./dragonfly-x86_64 -help
    dragonfly-x86_64: a modern in-memory store.
    
    Usage: dragonfly [FLAGS]
    
    
      Flags from facade/dragonfly_connection.cc:
        --http_admin_console (If true allows accessing http console on main TCP
          port); default: true;
        注释:是否允许访问主TCP端口的http控制台
        --tcp_nodelay (Configures dragonfly connections with socket option
          TCP_NODELAY); default: false;
        注释:是否使用套接字选项TCP_NODELAY配置dragonglu连接
      Flags from facade/dragonfly_listener.cc:
        --conn_threads (Number of threads used for handing server connections);
          default: 0;
        注释:用于处理服务器连接的线程数
        --conn_use_incoming_cpu (If true uses incoming cpu of a socket in order to
          distribute incoming connections); default: false;
        注释:为true时使用套接字传入CPU来分配传入连接
    --tls (); default: false;
        注释:是否开启tls连接
    --tls_client_cert_file (cert file for tls connections); default: "";
        注释:tls连接的证书文件
        --tls_client_key_file (key file for tls connections); default: "";
        注释:tls连接的关键文件
    
      Flags from server/dfly_main.cc:
        --bind (Bind address. If empty - binds on all interfaces. It's not advised
          due to security implications.); default: "";
        注释:绑定地址,为空时绑定所有接口()
    --pidfile (If not empty - server writes its pid into the file); default: "";
        注释:非空时服务器将其pid写入指定文件
        --use_large_pages (If true - uses large memory pages for allocations);
          default: false;
        注释:为真时使用大内存页分配
    
      Flags from server/engine_shard_set.cc:
    --backing_prefix (); default: "";
        注释:未知
        --cache_mode (If true, the backend behaves like a cache, by evicting entries
          when getting close to maxmemory limit); default: false;
        注释:为true时后端行为类似缓存,在接近最大内存限制时逐出条目
        --hz (Base frequency at which the server updates its expiry clock and
          performs other background tasks. Warning: not advised to decrease in
          production, because it can affect expiry precision for PSETEX etc.);
          default: 1000;
        注释:服务器更新其到期时钟并执行其他后台任务的基本频率(不建议减少,会影响PSETEX到期精度)
      Flags from server/generic_family.cc:
    --dbnum (Number of databases); default: 16;
        注释:数据库上限
        --keys_output_limit (Maximum number of keys output by keys command);
          default: 8192;
        注释:keys命令输出的最大键数
      Flags from server/io_mgr.cc:
        --backing_file_direct (If true uses O_DIRECT to open backing files);
          default: false;
        注释:为true时使用O_DIRECT打开备份文件
      Flags from server/list_family.cc:
        --list_compress_depth (Compress depth of the list. Default is no
          compression); default: 0;
        注释:list的压缩深度,默认不压缩
        --list_max_listpack_size (Maximum listpack size, default is 8kb);
          default: -2;
        注释:最大listpack大小,默认8kb
      Flags from server/main_service.cc:
        --maxmemory (Limit on maximum-memory that is used by the database.0 - means
          the program will automatically determine its maximum memory usage);
          default: 0;
        注释:数据库使用的最大内存限制。0-表示程序将自动确定其最大内存使用量
    --memcache_port (Memcached port); default: 0;
        注释:Memcached端口号
        --port (Redis port); default: 6379;
        注释:Redis端口号
      Flags from server/server_family.cc:
    --dbfilename (the filename to save/load the DB); default: "dump";
        注释:保存/加载数据库文件名
    --dir (working directory); default: "";
        注释:工作目录
        --requirepass (password for AUTH authentication); default: "";
        注释:身份验证密码
      Flags from server/tiered_storage.cc:
        --tiered_storage_max_pending_writes (Maximal number of pending writes per
          thread); default: 32;
        注释:每个线程最大挂起写入数
    
      Flags from helio/util/proactor_pool.cc:
        --proactor_threads (Number of io threads in the pool); default: 0;
        注释:线程池中io线程数目
    
      Flags from helio/util/uring/proactor.cc:
        --proactor_register_fd (If true tries to register file descriptors);
          default: false;
        注释:是否注册文件描述符
        --proactor_spin_limit (How many times to spin proactor loop before blocking
          on kernel); default: 10;
        注释:内核阻塞前旋转proactor循环次数
    Try --helpfull to get a list of all flags or --help=substring shows help for
    flags which include specified substring in either in the name, or description or
    path.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

      开启客户端后就能正常输入命令,对于dragonfly的命令兼容了memcache和redis的API,基本保持一致了,目前已经实现了大部分的命令(),详细的命令参数可见:dragonfly API
    在这里插入图片描述
      dragonfly在本地端口制作了一个网页(redis是没有的),能够显示当前的一些信息,主要就是对于一些时延的统计什么的,每次需要刷新一下才能看到实时情况:
    在这里插入图片描述

    二、dragonfly本身的特点

      dragonfly一出来就号称比redis快25倍,同属于内存数据库,能做到这点肯定是有一些特殊的设计,下面就来介绍一下dragonfly的特点:

      1)特点1:多线程

      与redis的单线程设计不同,dragonfly使用多线程进行响应服务。多线程的设计更加符合现代计算机的多核设计,能够更大化的利用系统资源。

      2)特点2:无共享架构

      redis使用单线程结构,不涉及共享。而dragonfly作为多线程,对于多线程的数据传输也没有使用共享架构。对此原因有以下三点:
      (1)可以在公有云中可用服务器充分利用CPU,内存和IO资源,允许线程之间对内存存储键空间分区,每个线程管理自己的数据切
      (2)共享架构可为所有的操作提供原子性的保证,在非常高的吞吐量上保证低时延
      (3)在多CPU的情况下,没有共享架构就不需要停等,CPU的利用率会上升

      3)特点3:新型的锁管理器

      dragonfly为了提供更好的原子性保证,用了一种VLL的新型锁管理器来开发事务框架。借此可以允许在不使用互斥锁或者自旋锁的情况下编写原子操作。

      4)特点4:更多的数据结构

      dragonfly保持了原有的redis的基础数据结构(string set list zset hashset),同时基于hash表开发了一个Dashtable结构保证更好的性能
      关于dash的详细描述在这里(其实是我也没看懂,不知道咋解释~):dragonfly/dashtable

    三、redis和dragonfly的对比

      dragonfly一出来就直接对飙redis,说自己可能是宇宙中最快的数据库,比redis快了25倍。对此dragonfly和redis的官方都做出了回应,下面来看看具体的内容吧。

      1)dragonfly官方

      dragonfly官方做了两部分的测试,一个是通过基础测试程序反应的每秒访问次数,另外一个是对内存效率进行测试。
      先来看看环境:dragonfly肯定是单服务器多线程了,对于redis选择的是单服务器单实例进程。
      最后每秒访问次数的结果如下图(图可以在github上找到),dragonfly达到redis25倍性能,在单例(多线程)情况下支持每秒百万次的查询率
    在这里插入图片描述
      至于内存效率,分成了两个阶段:空闲阶段(单纯进行查询)、快照阶段(指为了持久性从内存向磁盘的备份阶段),从下面图的结果上看,在空闲阶段下,dragonfly的性能要优于redis30%左右,快照阶段优于一倍多,而且能够保持稳定。
    在这里插入图片描述
      从表面的数据上看,dragonfly确实优于redis。但我个人认为对于比较细节描述的不是很详细,有点儿云里雾里的感觉。

      2)Redis官方:

      对于dragonfly的表示,redis官方也给出了回应。回应的详细内容在这里:13 Years Later - Does Redis Need a New Architecture? | Redis
      redis官方认为这样比较是不公平的,他认为单个进程实例不是redis在真实世界的运行模式,redis有集群体制,使用集群才能发挥redis的性能,才能更公平公正的比较出效果。于是redis官方又使用相同的示例数据做了对比实验
      说说环境:redis官方使用redis7.0,用40个节点分片(等同于40个服务器)构成集群和单台机器上dragonfly的64核做比较。得到的实验结果如下:
    在这里插入图片描述
      从结果上看,无论是单通道还是多通道,redis的吞吐量都比dragonfly高18%-40%
      其次redis只使用到了vCPU64个其中的40个,而dragongfly用满了64个,暗含redis性能还能提高的意思
    在这里插入图片描述
      从实验结果上看,两家各有说法。不过dragonfly的出现也引发了redis对于存储结构的思考。是单线程集群式(横向扩展)还是单机式多线程更好(纵向扩展)。对此redis官方在回应中认为是横向更好,并给出了多点原因的介绍:

      更佳弹性——我们在集群中使用的节点越多,整个集群的健壮性就越强。例如,如果您在三节点集群上运行数据集,且其中一个节点发生降级,则代表有三分之一的集群无法运行;但如果是在九节点集群上运行数据集,同样是其中一个节点发生降级,则只有九分之一的集群无法运行。
      易于扩展——在横向扩展系统当中,向集群添加一个额外节点、并将数据集的一部分迁移到其中要容易得多。与之对应,在纵向扩展系统中,我们只能直接引入一个更大的节点并复制整个数据集……这是个漫长的过程,而且期间随时有可能闹出麻烦。
      逐步扩展更具成本效益——纵向扩展,尤其是云环境下的纵向扩展,往往对应高昂的成本。在多数情况下,即使只需要向数据集内添加几 GB 内容,也需要将实例大小翻倍。
      高吞吐——在 Redis,我们看到很多客户会在小型数据集上运行高吞吐量工作负载,即具有极高的网络带宽及 / 或每秒数据包(PPS)需求。我们以每秒操作数 100 万 + 的 1 GB 大小数据集为例,相较于使用单节点 c6gn.16xlarge 集群(128 GB 内存、64 个 CPU 加 100 Gbps 传输带宽,每小时使用成本 2.7684 美元),三个 c6gb.xlarge 节点(8 GB 内存、4 个 CPU 外加最高 25 Gbps 传输带宽,每小时 0.1786 美元)构成的集群能够将运行成本拉低 20%,而且健壮性反而更高。既然成本效益出色、弹性更强且吞吐量反超,那横向扩展无疑就是比纵向扩展更好的选择。
      贴近 NUMA 架构——纵向扩展还要求使用能容纳更多核心和大容量 DRAM 的双插槽服务器;相比之下,Redis 这样的多处理架构其实更适应 NUMA 架构,因为其行为特征就接近一种由多个较小节点组成的网络。但必须承认,NUMA 跟多线程架构之间也有天然冲突。根据我们在其他多线程项目中的经验,NUMA 可能令内存数据存储的性能降低达 80%。
      存储吞吐量限制——AWS EBS 等外部磁盘的扩展速度,显然不及内存和 CPU。事实上,云服务商会根据所使用设备的类型添加存储吞吐量限制。因此,避免吞吐量限制、满足数据高持久性要求的唯一办法,就是使用横向扩展——即添加更多节点和更多的配套网络附加磁盘。
      临时磁盘——临时磁盘是一种将 Redis 运行在 SSD 上的绝佳方式(其中 SSD 用于替代 DRAM,而非充当持久存储介质),能够在保持 Redis 极高速度的同时将数据库成本保持在磁盘级水平。但临时磁盘也有其上限,一旦逼近这一上限,我们还需要进一步扩展容量——这时候,更好的办法仍然是添加更多节点、引入更多临时磁盘。所以,横向扩展继续胜出。
      商品硬件——最后,我们的很多客户会在本地数据中心、私有云甚至是小型边缘数据中心内运行 Redis。在这类环境中,绝大多数设备内存不超过 64 GB、CPU 不超过 8 个,所以唯一可行的扩展方式就只有横向扩展

    参考:https://mp.weixin.qq.com/s/rwK6e2ZuXNUsABES7TpqRg

      除了两官方给出的测试比较外,其实dragonfly在实现细节上也和redis产生了一些不同:
      1)string长度256MB
      2)过期时间限制在4年
      3)支持lua intergers

    四、实操测试

      光听官方说,也不知道谁说的对,还是自己使用测试工具测试一下。在此使用的开源测试工具是ycsb。这个工具专门用来测试nosql的性能,其中包含了redis,刚好dragonfly兼容了redis的接口,所以也没问题。
      先介绍一下ycsb吧!
      源码见:GitHub - brianfrankcooper/YCSB: Yahoo! Cloud Serving Benchmark
      这个源码是基于java的,所以使用前先安装java环境(sudo apt-get -y install openjdk-11-jdk)

      代码执行的时候可能报错:/usr/bin/env: ‘python’: No such file or directory
      解决办法见:解决:/usr/bin/env: ‘python’: No such file or directory

      对于ycsb的使用可以参考:YCSB性能测试工具使用

      下面开始对比测试,步骤如下:
      1)开服务器端
      2)执行测试命令

      第一组测试使用redis的单线程进行测试,命令如下:

    bin/ycsb.sh load redis -s -P workloads/workloada -p "redis.host=127.0.0.1" -p "redis.port=6379"
    
    bin/ycsb.sh run redis -s -P workloads/workloada -p "redis.host=127.0.0.1" -p "redis.port=6379" \
     -p "operationcount=10000" -p "measurementtype=timeseries" \
     -p "timeseries.granularity=5000"
    
    • 1
    • 2
    • 3
    • 4
    • 5

      对命令进行下解读,在这个命令中设置了1000条命令(后台文件配置),measurementtype会配置Measurements输出时间序列而不是直方图,operationcount表示总共操作次数,使用的YCSB实例操作数,measurementtype是显示延迟测量的方式为timeseries同时设置

      为了让数据更有说服力,选择其中的关键信息保存,然后将实验进行5次

      读写比1:1
      redis统计结果如下(小数位省略):
    在这里插入图片描述
      dragonfly统计结果如下(小数位省略):
    在这里插入图片描述

      读写比9:1
      redis统计结果(小数位省略):
    在这里插入图片描述
      dragonfly统计结果(小数位省略):
    在这里插入图片描述
      读写比1:9
      redis统计结果(小数位省略):
    在这里插入图片描述

      dragonfly统计结果(小数位省略)
    在这里插入图片描述
    留一下redis使用:
    ubuntu20.04安装redis参考:
    https://blog.csdn.net/m0_57394815/article/details/124051159
    redis使用:

    cd /usr/local/redis
    ./src/redis-server
    ./src/redis-cli
    
    • 1
    • 2
    • 3

    学习过程中,看到一些参考资料,在此标注:
    Dragonfly安装&配置 Redis和Memcached的现代替代品
    redis VS dragonfly(更支持redis):Redis老了吗?Redis与Dragonfly性能比较 (jdon.com)

    因作者水平有限,如有错误之处,请在下方评论区指正,谢谢!

  • 相关阅读:
    外汇天眼:经济衰退无阻加息,欧美货币政策齐收紧
    yolov5+shufflenet轻量化目标检测
    每头奶牛谋定身份 国稻种芯-泰兴:牧场智能化的饲养管理
    节日网页HTML代码 学生网页课程设计期末作业下载 清明节大学生网页设计制作成品下载 DW节日网页作业代码下载
    多台主机使用DNS服务器实现网络负载均衡
    全量知识系统 程序详细设计 库模式的存储库模型: “三生”(派生衍生自生) (Q&A SmartChat)
    Elasticsearch:了解人工智能搜索算法
    09 区间估计
    记一次 .NET 某汽贸店 CPU 爆高分析
    [附源码]Python计算机毕业设计Django天狗电子商城系统
  • 原文地址:https://blog.csdn.net/gls_nuaa/article/details/126408445