InnoDB Cluster集群Mysql Router代理层最佳实践

news2024/11/24 2:04:38

InnoDB Cluster 集群 & Mysql-Router 代理层

前言

Mysql是现今最常用的关系型数据库之一,高可用一直是我们对软件服务的要求。常见的Mysql高可用是主从配置,在主节点挂掉后需要依赖监控脚本进行主从切换将从节点升级,后台服务代码层面也需要进行相关配置。那有没有更简约的办法做到后台代码零侵入呢,答案是有的,本文就采用 Mysql 官方的集群模式加官方的 Router 代理层实现 Mysql 对后台服务的隐藏,后台服务只需要像连接普通 Mysql 服务一样连接到 Router 即可。

这种方案优势非常明显:

  1. MySQL Router 是官方出品,是轻量级代理程序,后台应用不可见。
  2. Router 可自己实现读写分离。
  3. 数据库服务器故障,业务可以正常运行。由MySQL Router来进行自动下线不可用服务器和替换主节点。
    在这里插入图片描述
    现在直接把全套最佳实践正文发布如下(Docker版本三节点)。

1、InnoDB Cluster集群

1.1、Mysql8.0 standalone(建议至少3个节点才能保证高可用)

使用Mysql8.0镜像启动3个节点(一主两从),除server_idreport_host外其他配置均一致。

# docker-compose
services:
  mysql-server:
    # container_name: mysql-server
    image: mysql/mysql-server:8.0
    restart: always
    # volumes:
    # - /data/mysql-server:/var/lib/mysql
    network_mode: host
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_ROOT_HOST: '%'
    command: ["mysqld",
    "--server_id=1",
    "--report_host=$HOSTNAME", # 通信的ip地址
    "--report_port=3306", # 通信的端口
    "--binlog_checksum=NONE",
    "--gtid_mode=ON",
    "--enforce_gtid_consistency=ON",
    "--log_bin",
    "--log_slave_updates=ON",
    "--master_info_repository=TABLE",
    "--relay_log_info_repository=TABLE",
    "--transaction_write_set_extraction=XXHASH64",
    "--user=mysql",
    "--skip-host-cache",
    "--skip-name-resolve",
    "--default_authentication_plugin=mysql_native_password",
    "--binlog_transaction_dependency_tracking=WRITESET"]

1.2、使用mysql-shell建立集群

# 手动方式
mysqlsh --uri "root@mysql-server-1"
// init.js
var password = "root"
var clusterName = "mysqlCluster"

try {
  print('Setting up InnoDB cluster...\n');
  shell.connect('root@127.0.0.1:3306', password)
  var cluster = dba.createCluster(clusterName);
  print('Adding instances to the cluster.');
  cluster.addInstance({user: "root", host: "127.0.0.1", port: 3307, password: password}, {recoveryMethod:'clone'})
  print('.');
  cluster.addInstance({user: "root", host: "127.0.0.1", port: 3308, password: password}, {recoveryMethod:'clone'})
  print('.\nInstances successfully added to the cluster.');
  print('\nInnoDB cluster deployed successfully.\n');
} catch(e) {
  print('\nThe InnoDB cluster could not be created.\n\nError: ' + e.message + '\n');
}

1.3、使用docker自动建立集群

1.3.1、docker-entrypoint.sh

#!/bin/bash
set -e

if [ -n "$1" ]; then
  exec "$@"
fi

if [ -z "$MYSQL_HOST" ]; then
  echo "-e MYSQL_HOST is required."
  exit 1
fi
if [ -z "$MYSQL_PORT" ]; then
  echo "-e MYSQL_PORT is required."
  exit 1
fi
if [ -z "$MYSQL_USER" ]; then
  echo "-e MYSQL_USER is required."
  exit 1
fi
if [ -z "$MYSQL_PASSWORD" ]; then
  echo "-e MYSQL_PASSWORD is required."
  exit 1
fi

max_tries=10
attempt_num=0
until (echo > "/dev/tcp/$MYSQL_HOST/$MYSQL_PORT") >/dev/null 2>&1; do
  echo "Waiting for mysql server $MYSQL_HOST ($attempt_num/$max_tries)"
  sleep $(( attempt_num++ ))
  if [ attempt_num -eq max_tries ]; then
    exit 1
  fi
done

if [ -n "$MYSQLSH_SCRIPT" ]; then
  mysqlsh "$MYSQL_USER@$MYSQL_HOST:$MYSQL_PORT" --password="$MYSQL_PASSWORD" -f "$MYSQLSH_SCRIPT" || true
fi
if [ -n "$MYSQL_SCRIPT" ]; then
  mysqlsh "$MYSQL_USER@$MYSQL_HOST:$MYSQL_PORT" --password="$MYSQL_PASSWORD" --sql -f "$MYSQL_SCRIPT" || true
fi

1.3.2、Dockerfile

FROM alpine:3.18 as download

ARG pkg='mysql-shell-8.0.33-linux-glibc2.12-x86-64bit'
RUN wget "https://dev.mysql.com/get/Downloads/MySQL-Shell/$pkg.tar.gz"

###
FROM debian:bullseye-slim

ARG pkg='mysql-shell-8.0.33-linux-glibc2.12-x86-64bit'
COPY --from=download "/$pkg.tar.gz" /opt
COPY docker-entrypoint.sh /bin/
RUN cd /opt && \
    tar -xzf "$pkg.tar.gz" && \
    ln -s "/opt/$pkg/bin/mysqlsh" /bin/ && \
    rm -f "/$pkg.tar.gz" && \
    chmod 755 /bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD []

1.3.3、docker-compose

services:
  mysql-shell:
    container_name: mysql-shell
    image: mysql-shell:8.0
    build: ./mysql-shell-builder
    restart: on-failure
    volumes:
    - ./scripts/:/scripts/
    environment:
    - MYSQL_HOST=mysql-server-1
    - MYSQL_PORT=3306
    - MYSQL_USER=root
    - MYSQL_PASSWORD=root
    - MYSQLSH_SCRIPT=/scripts/init.js
    - MYSQL_SCRIPT=/scripts/init.sql
    depends_on:
    - mysql-server-1
    - mysql-server-2
    - mysql-server-3

2、Mysql Router代理层

# docker-compose
services:
  mysql-router:
    container_name: mysql-router
    image: mysql/mysql-router:8.0
    restart: always
    ports:
    - 3306:6446
    environment:
    - MYSQL_HOST=mysql-server-1
    - MYSQL_PORT=3306
    - MYSQL_USER=root
    - MYSQL_PASSWORD=root
    - MYSQL_INNODB_NUM_MEMBERS=3 #Wait for this number of cluster instances to be online.
    - MYSQL_CREATE_ROUTER_USER=0
    depends_on:
    - mysql-server-1
    - mysql-server-2
    - mysql-server-3
    - mysql-shell

3、整合

3.1、目录结构

- <PROJECT_DIRECTORY>
  - mysql-shell-builder
    * docker-entrypoint.sh    * Dockerfile
  - scripts
    * init.js
    * init.sql [optional]
  * docker-compose.yaml

3.2、docker-compose.yaml

version: '3'

services:
  mysql-server-1:
    container_name: mysql-server-1
    image: mysql/mysql-server:8.0
    restart: always
    volumes:
    - /data/mysql-server-1:/var/lib/mysql
    # ports:
    # - 3301:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_ROOT_HOST: '%'
    command: ["mysqld","--server_id=1","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve","--default_authentication_plugin=mysql_native_password","--binlog_transaction_dependency_tracking=WRITESET"]

  mysql-server-2:
    container_name: mysql-server-2
    image: mysql/mysql-server:8.0
    restart: always
    volumes:
    - /data/mysql-server-2:/var/lib/mysql
    # ports:
    # - 3302:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_ROOT_HOST: '%'
    command: ["mysqld","--server_id=2","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve","--default_authentication_plugin=mysql_native_password","--binlog_transaction_dependency_tracking=WRITESET"]

  mysql-server-3:
    container_name: mysql-server-3
    image: mysql/mysql-server:8.0
    restart: always
    volumes:
    - /data/mysql-server-3:/var/lib/mysql
    # ports:
    # - 3303:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_ROOT_HOST: '%'
    command: ["mysqld","--server_id=3","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve","--default_authentication_plugin=mysql_native_password","--binlog_transaction_dependency_tracking=WRITESET"]

  mysql-shell:
    container_name: mysql-shell
    image: mysql-shell:8.0
    build: ./mysql-shell-builder
    restart: on-failure
    volumes:
    - ./scripts/:/scripts/
    environment:
    - MYSQL_HOST=mysql-server-1
    - MYSQL_PORT=3306
    - MYSQL_USER=root
    - MYSQL_PASSWORD=root
    - MYSQLSH_SCRIPT=/scripts/init.js
    # - MYSQL_SCRIPT=/scripts/init.sql
    depends_on:
    - mysql-server-1
    - mysql-server-2
    - mysql-server-3

  mysql-router:
    container_name: mysql-router
    image: mysql/mysql-router:8.0
    restart: always
    ports:
    - 3306:6446
    environment:
    - MYSQL_HOST=mysql-server-1
    - MYSQL_PORT=3306
    - MYSQL_USER=root
    - MYSQL_PASSWORD=root
    - MYSQL_INNODB_NUM_MEMBERS=3 #Wait for this number of cluster instances to be online.
    - MYSQL_CREATE_ROUTER_USER=0
    depends_on:
    - mysql-server-1
    - mysql-server-2
    - mysql-server-3
    - mysql-shell

后台启动

docker compose up -d

后记

官方平台,对服务透明,自动故障处理,想要的功能它都有。就是首次配置可能需要多花点时间,但是参考本文,相信你可以对这套实践有更快的理解,欢迎点赞收藏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/601258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

正在破坏您的协程(Coroutines)的无声杀手(Silent Killer)

正在破坏您的协程的无声杀手 处理 Kotlin 中的取消异常的唯一安全方法是不重新抛出它们。 今天生产服务器再次停止响应流量。 上个星期&#xff0c;你刚重新启动它们并将其视为故障。但是你总觉得有些奇怪&#xff0c;因为日志中没有任何错误的痕迹&#xff0c;甚至没有警告。…

vue cli配置代理解决跨域问题

跨域问题 是由于违背了同源策略&#xff0c;同源策略规定了协议名、主机名、端口号必须一致 我们目前所处的位置是http localhost 8080&#xff0c;我们想向一台服务器发送请求&#xff0c;它的位置是http localhost 5000&#xff0c;我们的ajax请求从浏览器发送到服务器&#…

界面组件DevExpress WPF中文指南 - 如何应用系统强调色及主题切换

在最新版本的Microsoft Office产品中&#xff0c;用户可以根据系统设置选择主题&#xff0c;当使用这个主题时&#xff0c;Office将采用Windows强调色和应用模式(亮/暗)设置&#xff0c;并将它们应用到Office本身。如果用户在操作系统中更改了强调色或应用模式&#xff0c;Offi…

【spring源码系列-02】通过refresh方法剖析IOC的整体流程

Spring源码系列整体栏目 内容链接地址【一】spring源码整体概述https://blog.csdn.net/zhenghuishengq/article/details/130940885【一】通过refresh方法剖析IOC的整体流程https://blog.csdn.net/zhenghuishengq/article/details/131003428 spring底层源码整体概述 一&#xff…

2个实际工作中的小技巧,先收再看(网工版)

大家好&#xff0c;我是老杨。 本来想发点关于快乐的文章&#xff0c;但我思来想去&#xff0c;对成年人最大的快乐&#xff0c;莫过于高效完成工作&#xff0c;早点下班回家。 关于提升工作效率这方面啊&#xff0c;我的文章其实零碎、分散的写过了很多次了。 你要知道&…

ChatGPT国内免费使用地址和开源公众号集成项目分享

ChatGPT国内免费使用地址和开源公众号集成项目分享 ChatGPT国内免费使用地址ChatGPT开源公众号集成项目ChatGPT国内免费调用API的地址总结免费体验地址 人工智能技术的快速发展&#xff0c;ChatGPT聊天机器人备受瞩目。然而&#xff0c;如何在国内免费使用ChatGPT却是许多人关注…

手绘echarts散点图

面对各种定制&#xff0c;echarts图表有时候不好处理&#xff0c;无论是数据处理还是样式处理&#xff0c;都会被echarts限制。 举例&#xff1a;echarts散点图如果数据较少&#xff0c;echarts会均匀分布&#xff0c;如图1 对于产品或者老板对页面的要求&#xff0c;认为中间…

ROS2中,从SolidWorks导出的urdf,联合moveit、gazebo进行控制及仿真

文章目录 1.前言2.从urdf到moveit3.从urdf到gazebo3.1.urdf文件的修改3.1.1.mesh路径3.1.2.零件起飞3.1.3.文件保存 3.2.xacro文件的修改3.3.launch 4.用moveit控制gazebo5.结语 1.前言 本文是对之前发的文章【在ROS2中&#xff0c;通过MoveIt2控制Gazebo中的自定义机械手】的…

C 语言详细教程

目录 第一章 C语言基础知识 第二章 数据类型、运算符和表达式 第三章 结构化程序设计 第四章 数组 第五章 函数 第六章 指针 第七章 结构体类型和自定义类型 第八章 编译预处理 第九章 文件 说明&#xff1a;本教程中的代码除一二三个之外&#xff0c;都在https://ligh…

尝试理解卷积神经和深度学习的关系,并且怎么使用

前言 最近想要了解卷积神经和深度学习,才发现并不是我想象中的简单,也不是我想象中的难.我想的难是指没有任何思路:不知道这是个什么玩意,里面的流程是不是很难,我想的简单就是:也就是用人家的包,全都是用来导包,我只需要知道这个包是怎么用的,从来没想过自己怎么开发出来一个依…

Python splitlines() 的使用

Python splitlines() 的作用 Python splitlines() 按照行(\r, \r\n, \n)分隔&#xff0c;返回一个包含各行作为元素的列表 Python splitlines()的注意事项 splitlines小括号里面的参数没有的时候,默认按照行(\r, \r\n, \n)分隔不带这些特殊的字符 如果这样splitlines(True)…

ISO21434 概述(一)

目录 一、ISO21434 1.1 目的 1.2 ISO21434文档组织结构 二、适用范围 三、引用标准 四、术语和缩写 4.1 术语 4.2 缩写 五、一般考虑 一、ISO21434 1.1 目的 本文件阐述了道路车辆内电气和电子&#xff08;E/E&#xff09;系统工程中的网络安全问题。通过确保对网络安…

Ansible的配置、主机清单、Ansible的脚本Playbook详解

文章目录 Ansible的配置配置文件 主机清单远程主机的分组变量 Ansible的脚本PlaybookPlaybook的文件格式YAMLansible-playbook的命令Playbook的基本语法变量 Ansible的配置 配置文件 Ansible是一款功能强大的自动化工具&#xff0c;可以实现对远程主机的管理和操作&#xff0…

华为认证 | HCIA-Datacom 考试大纲

今天给大家说点基础的&#xff0c;很多人对华为认证考试有了一定了解后&#xff0c;想要进一步了解具体的考试内容。 这篇先说HCIA-Datacom的具体考试大纲~ 01 华为HCIA-Datacom认证考试 02 华为HCIA-Datacom考试内容 HCIA-Datacom V1.0考试覆盖数通基础知识&#xff0c;包括&…

java 中的动态代理实现

1. 什么是代理模式 代理模式是常见的设计模式之一&#xff0c;顾名思义&#xff0c;代理模式就是代理对象具备真实对象的功能&#xff0c;并代替真实对象完成相应操作&#xff0c;并能够在操作执行的前后&#xff0c;对操作进行增强处理。&#xff08;为真实对象提供代理&…

表格软件有哪些?热门表格软件推荐

作为报表开发人员&#xff0c;我们经常需要使用各种表格软件来处理数据并生成清晰、易读的报表。在市面上&#xff0c;有许多不同类型的表格软件可供选择。下面我将列举7款热门的表格软件&#xff0c;并详细介绍其中一款优秀的软件—VeryReport。 编辑搜图 请点击输入图片描述…

Qt6.5.1+WebRTC学习笔记(九)运行官方示例(win10+vs2019)

前言 webrtc源码目录下&#xff0c;有个examples目录&#xff0c;里面放置着官方的示例&#xff0c;其有peerconnection示例。 一、问题 peerconnection示例分客户端和服务端&#xff0c;以win系统为例&#xff0c;编译后会在输出目录生成两个可执行文件 服务端程序可以正常…

【基于GD32E230的定时器级联M/T法电机测速】

前言 在有感电机控制中&#xff0c;获取电机转速是非常重要的步骤&#xff0c;转速获取越准确&#xff0c;控制电机时越方便&#xff0c;抛开霍尔不谈&#xff0c;这里讨论电机编码器。 目前常见的电机编码器按种类分为绝对值编码器和增量编码器&#xff0c;绝对值编码器相对…

厚积薄发,AR光学方案商光舟半导体于AWE 2023首次公开亮相

青亭网6月2日报道&#xff0c;国内AR光波导技术厂商“光舟半导体”&#xff08;深圳市光舟半导体技术有限公司&#xff09;在AWE 2023首次公开亮相&#xff0c;并展示了最新的AR光波导模组、光机/光引擎、汽车HUD三大产品。 光舟半导体成立于2020年1月&#xff0c;公司由AR光学…

5.8 几个常见JavaScript图表库

几个常见JavaScript图表库 目录1、 Chart.js2、 Chartist.js3、 Highcharts.js4、 D3.js5、 Plotly.js6、 ECharts.js7、 Google Charts8、Other Charts 目录 1、 Chart.js 官方网站&#xff1a; www.chartjs.org Chart.js 是一个基于 HTML5 Canvas 的 JavaScript 图表库&…