使用MySQL 8.2透明读/写分离,代价几何?(译文)

2023-11-17 15:24:53 浏览数 (3)

摘要:MySQL 8.2引入了透明读/写分离功能,MySQL 路由器可以自动将只读SQL路由到集群的只读节点。然而,MySQL路由器在此过程中需要对接收到的SQL进行一定程度的解析,以确定其是否为只读SQL。这个解析过程对系统性能会有怎样的影响呢?知名MySQL布道师Frédéric Descamps对此进行了测试,让我们一起看看他的分析。

关于号主,姚远:

  • Oracle ACE(Oracle和MySQL数据库方向)
  • 华为云最有价值专家
  • 《MySQL 8.0运维与优化》的作者
  • 拥有 Oracle 10g、12c和19c OCM等数十项数据库认证
  • 曾任IBM公司数据库部门经理
  • 20 年DBA经验,服务2万 客户
  • 精通C和Java,发明两项计算机专利

这里号主翻译了知名MySQL布道师Frédéric Descamps撰写的关于MySQL 8.2透明读/写分离性能的测试和分析。

原文网址:https://lefred.be/content/mysql-8-2-read-write-splitting-a-what-cost/

作者:Frédéric Descamps,Oracle公司MySQL社区经理,知名MySQL布道师 。

我们一直在等待它!它现在已经可用了!MySQL中的读/写分离!!

在之前的文章中,我们已经了解了MySQL 8.2的透明读/写拆分是什么,以及如何与MySQL Connector/Python一起使用。我对这一新功能表示欢迎,但我想了解它是否真的值得。应用程序是否能够从将读操作卸载到另一个节点中受益,并且使用MySQL路由器和解析请求是否会减慢连接速度?这些是我在本文中要介绍和回答的问题。

01

环境

为了执行测试,我使用以下环境:

  • Linux Kernel 5.15.0 – aarch64
  • MySQL Community Server 8.2.0
  • MySQL Router 8.2.0
  • sysbench 1.1.0 using LuaJIT 2.1.0-beta3
  • VM.Standard.A1.Flex – Neoverse-N1 (50 BogoMIPS) 4 cores
  • 24GB of RAM

MySQL InnoDB 集群在 3 台机器上运行,一台机器用于 MySQL 路由器和 Sysbench。

Sysbench 准备了 8 个表,每个表有 100000 条记录。

MySQL连接使用SSL。

02

MySQL InnoDB 集群

以下是 MySQL Shell 中集群的概述:

代码语言:javascript复制
JS > cluster.describe()
{
    "clusterName": "myCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "topology": [
            {
                "address": "mysql1:3306", 
                "label": "mysql1:3306", 
                "role": "HA"
            }, 
            {
                "address": "mysql2:3306", 
                "label": "mysql2:3306", 
                "role": "HA"
            }, 
            {
                "address": "mysql3:3306", 
                "label": "mysql3:3306", 
                "role": "HA"
            }
        ], 
        "topologyMode": "Single-Primary"
    }
}


JS > cluster.status()
{
    "clusterName": "myCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "mysql1:3306", 
        "ssl": "REQUIRED", 
        "status": "OK", 
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", 
        "topology": {
            "mysql1:3306": {
                "address": "mysql1:3306", 
                "memberRole": "PRIMARY", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "replicationLag": "applier_queue_applied", 
                "role": "HA", 
                "status": "ONLINE", 
                "version": "8.2.0"
            }, 
            "mysql2:3306": {
                "address": "mysql2:3306", 
                "memberRole": "SECONDARY", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "replicationLag": "applier_queue_applied", 
                "role": "HA", 
                "status": "ONLINE", 
                "version": "8.2.0"
            }, 
            "mysql3:3306": {
                "address": "mysql3:3306", 
                "memberRole": "SECONDARY", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "replicationLag": "applier_queue_applied", 
                "role": "HA", 
                "status": "ONLINE", 
                "version": "8.2.0"
            }
        }, 
        "topologyMode": "Single-Primary"
    }, 
    "groupInformationSourceMember": "mysql1:3306"
}

还有已经引导到集群的MySQL路由器,在MySQL路由器中我们可以看到所有的端口:

代码语言:javascript复制
JS > cluster.listRouters()
{
    "clusterName": "myCluster", 
    "routers": {
        "router.sub09280951550.mysqlgermany.oraclevcn.com::system": {
            "hostname": "router.subXXXXXXX.mysqlgermany.oraclevcn.com", 
            "lastCheckIn": "2023-11-15 09:27:18", 
            "roPort": "6447", 
            "roXPort": "6449", 
            "rwPort": "6446", 
            "rwSplitPort": "6450", 
            "rwXPort": "6448", 
            "version": "8.2.0"
        }
    }
}

03

OLTP 读/写

我们首先在主节点(端口 3306 )上使用 sysbench 的oltp_read_write.lua脚本,然后使用 MySQL 路由器的读/写专用端口 (端口6446) 再次运行它,最后使用读/写拆分端口 (端口6450)。测试使用 8 个线程,每次运行 3 次。

下面是测试使用的命令,主机和端口当然会变化:

代码语言:javascript复制
$ sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql 
   --mysql-user=sysbench --mysql-password=XxxxXX --mysql-ssl=REQUIRED 
   --mysql-host=<...> --mysql-port=<...> --tables=8 --table-size=100000 
   --threads=8 run

8 个线程并不多,在这个工作负载中也没有太多的争用,但我们可以看到差异很小。当然,分析每个事务/查询并将它们发送到不同的主机是有成本的。

04

OLTP 只读

这一次,我们再次运行 sysbench,但我们使用oltp_read_only.lua脚本。再次使用 8 个线程和 3 次运行:

我们在这里看到了更大的区别,因为没有写入,一台机器可以轻松处理满载。因此,解析请求并将其发送到多个服务器的成本更高。

当然,这只是因为单台服务器可以轻松地承担工作负载。

如果我们有一个只读工作负载,那么我建议使用 MySQL Router 的只读端口:6447

04

OLTP 只写

我们还使用脚本oltp_write_only.lua测试了只写工作负载。再次 8 个线程和 3 次运行:

我们可以看到,差异很小,但差异的确存在。

05

更复杂的工作负载

使用更复杂且优化程度较低的工作负载,例如oltp_update_non_index.lua,我们可以看到显著的差异。

06

结论

MySQL 8.2 的透明读/写分离是我们一直在等待的一个非常有趣的功能,它在性能方面的消耗非常低,它更加适合于查询模式稳定的应用,因为这样的应用会降低MySQL路由器解析SQL的成本。

您真的应该测试一下,并将您的意见发送给我们。

享受MySQL、MySQL路由器和所有集成解决方案(InnoDB ReplicaSet,InnoDB Cluster,InnoDB ClusterSet,InnoDB Read Replicas

推荐文章

0 人点赞