当前位置: 首页 > 面试题库 >

Redis AOF fsync(ALWAYS)与LSM树

窦国源
2023-03-14
问题内容

我对日志结构化合并树(LSM树)的理解是,通过将更新附加到预写日志中并返回到客户端,可以利用附加到磁盘的速度非常快(因为它不需要查找)这一事实。
我的理解是,这仍然提供了立即的持久性,同时仍然非常快。

我不认为Redis使用LSM树,Redis似乎具有一种模式,您可以在每次写入时进行AOF +
fsync。https://redis.io/topics/latency。该文档说:

AOF + fsync always: this is very slow, you should use it only if you know what you are doing.

我很困惑为什么这样做会很慢,因为原则上您仍然只在每次更新时都将文件追加到文件中,就像像Cassandra这样的LSM-tree数据库一样。


问题答案:

LSM是您有时希望实际阅读的AOF。您需要进行一些日常工作,以便以后可以更快地阅读。Redis的设计使您从不或仅在特殊情况下阅读它。另一方面,Cassandra经常读取它来处理请求。

对于像Cassandra这样的数据库,Redis所说的慢实际上是非常快的。

==========================更新

事实证明,我太早得出结论了。从设计的角度来看,上述所有内容都是正确的,但是实现方式却相差甚远。尽管Cassandra声称绝对耐用,但它并没有fsync在每个事务上,都没有办法强制执行此操作(但可以使每个事务同步)。我能做的最好的是“在以前的fsync之后至少1毫秒以批处理模式进行fsync”。这意味着对于我正在使用的4个线程基准测试,每个fsync执行4次写入操作,而线程正在等待fsync完成。另一方面,Redis每次写入都会执行fsync,因此频率提高了4倍。通过增加表的更多线程和分区,Cassandra可以赢得更大的收益。但是请注意,您描述的用例不是典型的。其他架构差异(Cassandra擅长分区,Redis擅长计数器,LUA等)仍然适用。

号码:

Redis命令: set(KEY + (tstate.i++), TEXT);

Cassandra命令: execute("insert into test.test (id,data) values (?,?)", state.i++, TEXT)

哪里 TEXT = "Wake up, Neo. We have updated our privacy policy."

每秒Redis fsync,硬盘

Benchmark              (address)   Mode  Cnt      Score      Error  Units
LettuceThreads.shared  localhost  thrpt   15  97535.900 ± 2188.862  ops/s

  97535.900 ±(99.9%) 2188.862 ops/s [Average]
  (min, avg, max) = (94460.868, 97535.900, 100983.563), stdev = 2047.463
  CI (99.9%): [95347.038, 99724.761] (assumes normal distribution)

Redis fsync每次写入,硬盘

Benchmark              (address)   Mode  Cnt   Score   Error  Units
LettuceThreads.shared  localhost  thrpt   15  48.862 ± 2.237  ops/s

  48.862 ±(99.9%) 2.237 ops/s [Average]
  (min, avg, max) = (47.912, 48.862, 56.351), stdev = 2.092
  CI (99.9%): [46.625, 51.098] (assumes normal distribution)

Redis,每次写入均同步,NVMe(Samsung 960 PRO 1TB)

Benchmark              (address)   Mode  Cnt    Score   Error  Units
LettuceThreads.shared     remote  thrpt   15  449.248 ± 6.475  ops/s

  449.248 ±(99.9%) 6.475 ops/s [Average]
  (min, avg, max) = (441.206, 449.248, 462.817), stdev = 6.057
  CI (99.9%): [442.773, 455.724] (assumes normal distribution)

Cassandra,每秒同步一次,硬盘

Benchmark                  Mode  Cnt      Score     Error  Units
CassandraBenchMain.write  thrpt   15  12016.250 ± 601.811  ops/s

  12016.250 ±(99.9%) 601.811 ops/s [Average]
  (min, avg, max) = (10237.077, 12016.250, 12496.275), stdev = 562.935
  CI (99.9%): [11414.439, 12618.062] (assumes normal distribution)

Cassandra,每批fsync,但至少要等待1毫秒,HDD

Benchmark                  Mode  Cnt    Score   Error  Units
CassandraBenchMain.write  thrpt   15  195.331 ± 3.695  ops/s

  195.331 ±(99.9%) 3.695 ops/s [Average]
  (min, avg, max) = (186.963, 195.331, 199.312), stdev = 3.456
  CI (99.9%): [191.637, 199.026] (assumes normal distribution)


 类似资料:
  • 带有 Node 和 commander.js 的 Linux 脚本管理器。 安装 npm install nlsm -g 使用 nlsm install **nlsm uninstall ** 支持的脚本 docker: https://get.docker.com/ ss,ssr,shadowsocks: https://github.com/teddysun/shadowsocks_insta

  • 问题内容: 在Java中,是否有一种方法可以使窗口始终位于“始终位于顶部”,而不管用户是否将焦点切换到另一个应用程序?我已经在网上搜索了所有的解决方案,它们都倾向于使用本机绑定的某种JNI接口。确实这不是唯一的方法吗?..还是吗? 问题答案: 尝试使用此类的方法: 它的工作方式与Windows TaskManager中的默认工作方式相同:切换到另一个应用程序,但始终显示在最前面。 这是在Java

  • 有没有办法停止以启动的docker容器,如下所示

  • 问题内容: 我是Android编程的新手,目前正在尝试使Actionbar运行。我的问题是,尽管我将XML文件中的一项设置为“ always”,但是无论我尝试什么,该项都会不断出现在溢出菜单中。我在这里发现了几个类似的问题,但是没有一个解决方案可以解决该问题。 附加信息:ic_action_search图标位于项目的可绘制文件夹中。 main_activity_actions.xml: strin

  • 在Kubernetes文档中,它提到使用的缓存语义使得ImagePullPolicy非常高效。我想选择不同的ImagePullPolicy的原因是什么?

  • 问题内容: 最初从映像运行Docker容器时,可以指定以下选项: 这样可以确保容器由于某种原因停止时始终由Docker守护程序重新启动。因此,您可以像这样运行一个容器: 您还可以通过指定其容器ID来重新启动现有的Docker容器,即: 但是,我无法确定是否有可能更改原本没有使用该选项运行的现有容器,以将其转换为以后始终重新启动。 目前,我能想到的唯一方法是将容器另存为新图像,然后使用该选项将该图像