我们如何在Tarantool数据库上实现缓存

美好的一天!

我想与您分享一个有关Tarantool数据库上缓存的实现及其工作特点的故事。
我在一家电信公司担任Java开发人员。 主要任务:公司从供应商那里购买的平台的业务逻辑的实现。 第一个功能是肥皂工作,几乎完全没有缓存,除了JVM内存。 在应用程序实例的数量超过两打之前,所有这些当然都是好的。

在工作过程中,以及对平台功能的了解的出现,人们尝试进行缓存。 当时,MongoDB已经启动,因此,我们没有像测试中那样得到任何特别的积极结果。

在进一步寻找我的好朋友mr_elzor的替代方案和建议后,决定尝试使用Tarantool数据库。

在粗略的研究中,唯一的疑问出现在lua中,因为我没有用“完全”一词写过它。 但是撇开所有疑虑,他着手安装。 关于封闭的网络和防火墙,我认为很少有人对此感兴趣,但是我建议您尝试绕开它们,并从公共来源收集所有内容。

使用以下配置测试服务器:8 Cpu,16 GB Ram,100 Gb HDD,Debian 9.4。

根据站点的说明进行安装。 因此,我有一个示例选项。 想法立即出现在可视界面上,通过该界面可以方便地进行支持。 在快速搜索中,我找到并配置了tarantool-admin 。 在Docker上工作,并至少目前支持100%的支持任务。

但是,让我们谈谈更有趣的事情。

下一个想法是在同一服务器内的主从配置中配置我的版本,因为文档仅包含具有两个不同服务器的示例。

花了一些时间了解lua并描述了配置之后,我启动了向导。

# systemctl start tarantool@master Job for tarantool@master.service failed because the control process exited with error code. See "systemctl status tarantool@master.service" and "journalctl -xe" for details. 

我立即陷入僵局,不知道为什么会出错,但我发现它处于“加载”状态。

 # systemctl status tarantool@master ● tarantool@master.service - Tarantool Database Server Loaded: loaded (/lib/systemd/system/tarantool@.service; enabled; vendor preset: enabled) Active: activating (start) since Tue 2019-02-19 17:03:24 MSK; 17s ago Docs: man:tarantool(1) Process: 20111 ExecStop=/usr/bin/tarantoolctl stop master (code=exited, status=0/SUCCESS) Main PID: 20120 (tarantool) Status: "loading" Tasks: 5 (limit: 4915) CGroup: /system.slice/system-tarantool.slice/tarantool@master.service └─20120 tarantool master.lua <loading> Feb 19 17:03:24 tarantuldb-tst4 systemd[1]: Starting Tarantool Database Server... Feb 19 17:03:24 tarantuldb-tst4 tarantoolctl[20120]: Starting instance master... Feb 19 17:03:24 tarantuldb-tst4 tarantoolctl[20120]: Run console at unix/:/var/run/tarantool/master.control Feb 19 17:03:24 tarantuldb-tst4 tarantoolctl[20120]: started 

我运行奴隶:

 # systemctl start tarantool@slave2 Job for tarantool@slave2.service failed because the control process exited with error code. See "systemctl status tarantool@slave2.service" and "journalctl -xe" for details. 

而且我看到了同样的错误。 在这里,我通常会开始紧张并不了解发生了什么,因为文档中根本没有关于它的内容……但是检查状态时,我看到它根本没有开始,尽管它说状态是“正在运行”:

 # systemctl status tarantool@slave2 ● tarantool@slave2.service - Tarantool Database Server Loaded: loaded (/lib/systemd/system/tarantool@.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Tue 2019-02-19 17:04:52 MSK; 27s ago Docs: man:tarantool(1) Process: 20258 ExecStop=/usr/bin/tarantoolctl stop slave2 (code=exited, status=0/SUCCESS) Process: 20247 ExecStart=/usr/bin/tarantoolctl start slave2 (code=exited, status=1/FAILURE) Main PID: 20247 (code=exited, status=1/FAILURE) Status: "running" Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: tarantool@slave2.service: Unit entered failed state. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: tarantool@slave2.service: Failed with result 'exit-code'. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: tarantool@slave2.service: Service hold-off time over, scheduling restart. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: Stopped Tarantool Database Server. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: tarantool@slave2.service: Start request repeated too quickly. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: Failed to start Tarantool Database Server. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: tarantool@slave2.service: Unit entered failed state. Feb 19 17:04:52 tarantuldb-tst4 systemd[1]: tarantool@slave2.service: Failed with result 'exit-code'. 

但与此同时,大师开始工作:

 # ps -ef | grep taran taranto+ 20158 1 0 17:04 ? 00:00:00 tarantool master.lua <running> root 20268 2921 0 17:06 pts/1 00:00:00 grep taran 

重新启动从站无济于事。 我想知道为什么吗?

我停下主人。 并以相反的顺序执行操作。

我看到奴隶正在尝试启动。

 # ps -ef | grep taran taranto+ 20399 1 0 17:09 ? 00:00:00 tarantool slave2.lua <loading> 

我启动向导,发现它没有升高,通常切换为孤立状态,而奴隶通常掉下来。

 # ps -ef | grep taran taranto+ 20428 1 0 17:09 ? 00:00:00 tarantool master.lua <orphan> 

它变得更加有趣。

我在从属服务器的日志中看到,他甚至看到了主服务器并试图进行同步。

 2019-02-19 17:13:45.113 [20751] iproto/101/main D> binary: binding to 0.0.0.0:3302... 2019-02-19 17:13:45.113 [20751] iproto/101/main I> binary: bound to 0.0.0.0:3302 2019-02-19 17:13:45.113 [20751] iproto/101/main D> binary: listening on 0.0.0.0:3302... 2019-02-19 17:13:45.113 [20751] iproto D> cpipe_flush_cb: locking &endpoint->mutex 2019-02-19 17:13:45.113 [20751] iproto D> cpipe_flush_cb: unlocking &endpoint->mutex 2019-02-19 17:13:45.113 [20751] main D> cbus_endpoint_fetch: locking &endpoint->mutex 2019-02-19 17:13:45.113 [20751] main D> cbus_endpoint_fetch: unlocking &endpoint->mutex 2019-02-19 17:13:45.113 [20751] main/101/slave2 I> connecting to 1 replicas 2019-02-19 17:13:45.113 [20751] main/106/applier/replicator@tarantuldb-t D> => CONNECT 2019-02-19 17:13:45.114 [20751] main/106/applier/replicator@tarantuldb-t I> remote master 825af7c3-f8df-4db0-8559-a866b8310077 at 10.78.221.74:3301 running Tarantool 1.10.2 2019-02-19 17:13:45.114 [20751] main/106/applier/replicator@tarantuldb-t D> => CONNECTED 2019-02-19 17:13:45.114 [20751] main/101/slave2 I> connected to 1 replicas 2019-02-19 17:13:45.114 [20751] coio V> loading vylog 14 2019-02-19 17:13:45.114 [20751] coio V> done loading vylog 2019-02-19 17:13:45.114 [20751] main/101/slave2 I> recovery start 2019-02-19 17:13:45.114 [20751] main/101/slave2 I> recovering from `/var/lib/tarantool/cache_slave2/00000000000000000014.snap' 2019-02-19 17:13:45.114 [20751] main/101/slave2 D> memtx_tuple_new(47) = 0x7f99a4000080 2019-02-19 17:13:45.114 [20751] main/101/slave2 I> cluster uuid 4035b563-67f8-4e85-95cc-e03429f1fa4d 2019-02-19 17:13:45.114 [20751] main/101/slave2 D> memtx_tuple_new(11) = 0x7f99a4004080 2019-02-19 17:13:45.114 [20751] main/101/slave2 D> memtx_tuple_new(17) = 0x7f99a4008068 

尝试成功了:

 2019-02-19 17:13:45.118 [20751] main/101/slave2 D> memtx_tuple_new(40) = 0x7f99a40004c0 2019-02-19 17:13:45.118 [20751] main/101/slave2 I> assigned id 1 to replica 825af7c3-f8df-4db0-8559-a866b8310077 2019-02-19 17:13:45.118 [20751] main/101/slave2 D> memtx_tuple_new(40) = 0x7f99a4000500 2019-02-19 17:13:45.118 [20751] main/101/slave2 I> assigned id 2 to replica 403c0323-5a9b-480d-9e71-5ba22d4ccf1b 2019-02-19 17:13:45.118 [20751] main/101/slave2 I> recover from `/var/lib/tarantool/slave2/00000000000000000014.xlog' 2019-02-19 17:13:45.118 [20751] main/101/slave2 I> done `/var/lib/tarantool/slave2/00000000000000000014.xlog' 

它甚至开始了:

 2019-02-19 17:13:45.119 [20751] main/101/slave2 D> systemd: sending message 'STATUS=running' 

但是由于未知的原因,他失去了联系并跌倒了:

 2019-02-19 17:13:45.129 [20751] main/101/slave2 D> SystemError at /build/tarantool-1.10.2.146/src/coio_task.c:416 2019-02-19 17:13:45.129 [20751] main/101/slave2 tarantoolctl:532 E> Start failed: /usr/local/share/lua/5.1/http/server.lua:1146: Can't create tcp_server: Input/output error 

再次尝试启动奴隶并没有帮助。

现在删除实例创建的文件。 就我而言,我从/ var / lib / tarantool目录中删除所有内容。

我先启动从站,然后再启动主站。 瞧...

 # ps -ef | grep tara taranto+ 20922 1 0 17:20 ? 00:00:00 tarantool slave2.lua <running> taranto+ 20933 1 1 17:21 ? 00:00:00 tarantool master.lua <running> 

除了作为“此软件的功能”之外,我没有找到任何有关此行为的解释。
如果服务器完全重新引导,则每次都会出现这种情况。

在对该软件的体系结构进行进一步分析后,事实证明,计划仅对一个实例使用一个vCPU,并且还有更多资源可用。

在n个vCPU的思想中,我们可以提升主设备和n-2个从设备来进行读取。

假设在测试服务器8个vCPU上,我们可以提升master和6个实例以进行读取。
我将文件复制为slave,更正端口并运行,即 添加了更多的奴隶。

重要! 添加另一个实例时,必须在向导中注册它。
但是您必须首先启动一个新的从属服务器,然后再重新启动主服务器。

例子


我已经有一个带有向导和两个从属的配置。

我决定增加第三个奴隶。

我在主机上注册了它,然后首先重新启动了主机,这就是我看到的内容:

 # ps -ef | grep tara taranto+ 20922 1 0 Feb19 ? 00:00:29 tarantool slave2.lua <running> taranto+ 20965 1 0 Feb19 ? 00:00:29 tarantool slave3.lua <running> taranto+ 21519 1 0 09:16 ? 00:00:00 tarantool master.lua <orphan> 

即 我们的主人成了独来独往的人,复制分裂了。

启动新的奴隶将不再有帮助,并会导致错误:

 # systemctl restart tarantool@slave4 Job for tarantool@slave4.service failed because the control process exited with error code. See "systemctl status tarantool@slave4.service" and "journalctl -xe" for details. 

在日志中,我看到了一些有用的条目:

 2019-02-20 09:20:10.616 [21601] main/101/slave4 I> bootstrapping replica from 3c77eb9d-2fa1-4a27-885f-e72defa5cd96 at 10.78.221.74:3301 2019-02-20 09:20:10.617 [21601] main/106/applier/replicator@tarantuldb-t I> can't join/subscribe 2019-02-20 09:20:10.617 [21601] main/106/applier/replicator@tarantuldb-t xrow.c:896 E> ER_READONLY: Can't modify data because this instance is in read-only mode. 2019-02-20 09:20:10.617 [21601] main/106/applier/replicator@tarantuldb-t D> => STOPPED 2019-02-20 09:20:10.617 [21601] main/101/slave4 xrow.c:896 E> ER_READONLY: Can't modify data because this instance is in read-only mode. 2019-02-20 09:20:10.617 [21601] main/101/slave4 F> can't initialize storage: Can't modify data because this instance is in read-only mode. 

我们停止向导并启动一个新的奴隶。 第一次启动时也会出现错误,但我们会看到它处于加载状态。

 # ps -ef | grep tara taranto+ 20922 1 0 Feb19 ? 00:00:29 tarantool slave2.lua <running> taranto+ 20965 1 0 Feb19 ? 00:00:30 tarantool slave3.lua <running> taranto+ 21659 1 0 09:23 ? 00:00:00 tarantool slave4.lua <loading> 

但是,当您启动主服务器时,新的从服务器将崩溃,并且主服务器不会处于运行状态。

 # ps -ef | grep tara taranto+ 20922 1 0 Feb19 ? 00:00:29 tarantool slave2.lua <running> taranto+ 20965 1 0 Feb19 ? 00:00:30 tarantool slave3.lua <running> taranto+ 21670 1 0 09:23 ? 00:00:00 tarantool master.lua <orphan> 

在这种情况下,只有一种出路。 如前所述,我删除了由实例创建的文件,然后先运行从属服务器,然后运行主服务器。

 # ps -ef | grep tarantool taranto+ 21892 1 0 09:30 ? 00:00:00 tarantool slave4.lua <running> taranto+ 21907 1 0 09:30 ? 00:00:00 tarantool slave3.lua <running> taranto+ 21922 1 0 09:30 ? 00:00:00 tarantool slave2.lua <running> taranto+ 21931 1 0 09:30 ? 00:00:00 tarantool master.lua <running> 

一切都成功启动。

这样,通过反复试验,我弄清楚了如何正确配置和启动复制。

结果,组装了以下配置:

2台服务器。
2个大师。 热储备。
12个奴隶。 所有都处于活动状态。

在tarantool的逻辑中,使用http.server的目的是不阻止其他适配器(记住供应商,平台和肥皂)或将库固定到每个业务流程。

为了避免主机之间的差异,在平衡器(NetScaler,HAProxy或您喜欢的任何其他设备)上,我们设置了保留规则,即 插入,更新,删除操作仅转到第一个活动的主服务器。

此时,第二个仅复制第一个中的记录。 从站本身已从配置连接到第一个指定的主站,这是我们在这种情况下需要的。

在lua上,对键值实施CRUD操作。 目前,这足以解决问题。

鉴于使用肥皂的功能,实施了代理业务流程,其中奠定了通过http处理狼蛛的逻辑。

如果密钥数据存在,则立即返回。 如果不是,则将请求发送到主系统,并将其存储在Tarantool数据库中。

结果,测试中的一个业务流程最多可以处理4k个请求。 在这种情况下,狼蛛的响应时间约为1毫秒。 平均响应时间最长为3ms。

这是测试的一些信息:



有50个业务流程进入4个主系统并在其内存中缓存数据。 在每个实例中,信息的复制都在全面增长。 鉴于Java已经热爱内存了……前景并不是最好的。

现在


50个业务流程通过缓存请求信息。 现在,来自该向导的4个实例的信息存储在一个位置,而不是在每个实例中都缓存在内存中。 可以显着减少主系统上的负载,没有信息重复,并且具有业务逻辑的实例上的内存消耗减少了。

狼蛛存储器中信息存储大小的示例:



最终,这些数字可能会翻倍,但性能不会下降。

在战斗中,当前版本每秒会产生2k-2.5k的实际负载请求。 平均响应时间类似于3ms以下的测试。

如果使用tarantool查看其中一台服务器上的htop,我们将看到它们正在“冷却”:



总结


尽管有Tarantool数据库的所有细微差别,您仍可以实现出色的性能。

我希望这个项目能够发展,这些不愉快的时刻将得到解决。

Source: https://habr.com/ru/post/zh-CN441686/


All Articles