CLOUD PAAS / DATABASE

ฐานข้อมูล MySQL / MariaDB การจำลองแบบ Master-Slave

คู่มือนี้เรียบเรียงและปรับรูปแบบสำหรับ Ruk-Com Cloud PaaS ภาพหน้าจออาจแตกต่างเล็กน้อยตามเวอร์ชันของระบบ

คลิกหรือแตะภาพหน้าจอเพื่อดูรายละเอียดขนาดจริง

วัตถุประสงค์

บทความนี้อธิบายการใช้งาน ฐานข้อมูล MySQL / MariaDB การจำลองแบบ Master-Slave บน Ruk-Com Cloud PaaS โดยจัดลำดับขั้นตอนและจุดตรวจสอบสำหรับการนำไปใช้งานจริง

ก่อนเริ่มดำเนินการ

  • เข้าสู่ระบบด้วยบัญชีที่มีสิทธิ์จัดการ Environment ที่เกี่ยวข้อง
  • ตรวจสอบชื่อ Environment, Region และทรัพยากรเป้าหมายก่อนบันทึกการเปลี่ยนแปลง
  • สำรองข้อมูลหรือกำหนดแผนย้อนกลับก่อนแก้ไขระบบ Production

การจำลองแบบ Master-Slave ใช้เพื่อแก้ปัญหาต่าง ๆ เกี่ยวกับประสิทธิภาพการทำงาน รองรับการสำรองข้อมูลของฐานข้อมูลที่แตกต่างกันและเป็นส่วนหนึ่งของโซลูชันขนาดใหญ่เพื่อลดความล้มเหลวของระบบ ช่วยให้สามารถจำลองข้อมูลจากเซิร์ฟเวอร์ฐานข้อมูล (master) ไปยังเซิร์ฟเวอร์ฐานข้อมูลอย่างน้อยหนึ่งเซิร์ฟเวอร์ (slave) master log การอัปเดตซึ่งจะส่งผลไปยัง slave ซึ่ง slave จะแสดงข้อความที่ระบุว่าได้รับการอัปเดตสำเร็จซึ่งอนุญาตให้ส่งการอัปเดตในภายหลัง การจำลองแบบ Master-Slave สามารถเป็นแบบซิงโครนัสหรืออะซิงโครนัสก็ได้ ความแตกต่างเป็นเพียงช่วงเวลาของการเผยแพร่การเปลี่ยนแปลง หากการเปลี่ยนแปลงเกิดขึ้นกับ master และ slave ในเวลาเดียวกันจะเป็นแบบซิงโครนัส หากการเปลี่ยนแปลงถูกจัดคิวและเขียนในภายหลังจะเป็นแบบอะซิงโครนัส

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

เป้าหมายการใช้งานสำหรับการจำลองแบบในฐานข้อมูล MariaDB และ MySQL ประกอบด้วย:

  • Scale-out โซลูชัน
  • ความปลอดภัยของข้อมูล
  • การวิเคราะห์
  • การกระจายข้อมูลทางไกล

คุณสามารถใช้การจำลองแบบดังกล่าวและใช้ประโยชน์จากมันได้อย่างไร

  • Backups: เพื่อใช้การจำลองแบบเป็นโซลูชันสำรองจำลองข้อมูลจาก master ไปยัง slave แล้วสำรองข้อมูล slave ซึ่ง slave สามารถหยุดชั่วคราวและปิดเครื่องได้โดยไม่ส่งผลกระทบต่อการทำงานของ master เพื่อให้คุณสามารถสร้าง snapshot ของข้อมูล "live" ที่มีประสิทธิภาพได้มิฉะนั้นจะต้องปิดตัว master
  • Scale-out: คุณสามารถใช้การจำลองแบบเป็น scale-out โซลูชัน นั่นคือที่ที่คุณต้องการแบ่งภาระงานคิวรี่ฐานข้อมูลจำนวนมากในเซิร์ฟเวอร์ฐานข้อมูลหลายตัวภายในข้อจำกัดที่สมเหตุสมผล เนื่องจากการจำลองแบบทำงานจากการแจกจ่าย master หนึ่งไปยัง slave หนึ่งตัวขึ้นไป ใช้สำหรับ scale-out จะทำงานได้ดีที่สุดใน Env ที่คุณมีจำนวนการอ่านสูง และการเขียน / อัปเดตน้อย
  • Spreading the load: อาจมีสถานการณ์เมื่อคุณมี master เดียวและต้องการจำลองฐานข้อมูลที่แตกต่างกันไปยัง slave ที่แตกต่างกัน ตัวอย่างเช่นคุณอาจต้องการกระจายข้อมูลการขายไปยังแผนกที่จำเป็นเท่านั้นเพื่อช่วยกระจายภาระระหว่างการวิเคราะห์ข้อมูล
  • Increasing the performance: เมื่อจำนวน slave ที่เชื่อมต่อกับ master เพิ่มขึ้น ภาระงานนั้นแม้ว่าจะน้อยที่สุด แต่ก็เพิ่มขึ้นเช่นกันเนื่องจาก slave แต่ละตัวใช้การเชื่อมต่อ client กับ master เนื่องจาก slave แต่ละตัวต้องได้รับสำเนาทั้งหมดของไบนารี log ภาระงานของเครือข่ายบน master อาจเพิ่มขึ้นและสร้างปัญหาคอขวด หากคุณใช้ slave จำนวนมากที่เชื่อมต่อกับ master หนึ่งตัวและ master ตัวนั้นก็กำลังดำเนินการตามคำขอ (เช่น เป็นส่วนหนึ่งของ scale-out โซลูชัน) คุณอาจต้องการปรับปรุงประสิทธิภาพของกระบวนการจำลองแบบ วิธีหนึ่งในการปรับปรุงประสิทธิภาพของกระบวนการจำลองแบบคือการสร้างโครงสร้างการจำลองแบบที่ลึกขึ้น ซึ่งช่วยให้ master สามารถจำลองเป็น slave เพียงตัวเดียวและสำหรับ slave ที่เหลือสามารถเชื่อมต่อกับ slave ตัวหลักสำหรับข้อกำหนดในการจำลองแบบได้
  • Failover alleviating: คุณสามารถตั้งค่า master และ slave (หรือ slave หลายตัว) และเขียนสคริปต์ที่คอยตรวจสอบ master เพื่อตรวจสอบว่ามันขึ้นหรือไม่ จากนั้นสั่งให้แอปพลิเคชันและ slave เปลี่ยน master ในกรณีที่เกิดความล้มเหลว
  • Security: คุณสามารถใช้ SSL เพื่อเข้ารหัสการถ่ายโอนไบนารี log ที่จำเป็นในระหว่างการจำลองแบบ แต่ทั้ง master และ slave ต้องรองรับการเชื่อมต่อเครือข่าย SSL หากโฮสต์ใดไม่รองรับการเชื่อมต่อ SSL การจำลองแบบผ่านการเชื่อมต่อ SSL จะไม่สามารถทำได้ การตั้งค่าการจำลองแบบโดยใช้การเชื่อมต่อ SSL คล้ายกับการตั้งค่าเซิร์ฟเวอร์และไคลเอนต์โดยใช้ SSL คุณต้องได้รับ (หรือสร้าง) ใบรับรองความปลอดภัยที่เหมาะสมซึ่งคุณสามารถใช้ได้กับ master และใบรับรองที่คล้ายกัน (จากผู้ออกใบรับรองเดียวกัน) ใน slave แต่ละตัว

ตอนนี้เรามาดูตัวอย่างง่าย ๆ ของวิธีกำหนดค่าการจำลองแบบ Master-Slave บน Ruk-Com PaaS กัน

คุณสามารถตั้งค่าคลัสเตอร์ฐานข้อมูลได้สองวิธี:

การติดตั้ง One-Click

คุณสามารถรับคลัสเตอร์ฐานข้อมูล MySQL หรือ MariaDB ที่มีประเภทการจำลองแบบที่ต้องการ (รวมถึง master-slave one) และทำงานภายในไม่กี่นาทีโดยใช้วิดเจ็ตติดตั้ง Ruk-Com one-click

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

ขั้นตอนนี้ง่ายมากเพียงระบุอีเมลของคุณและยืนยันผ่านการแจ้งเตือน อ่านบทความMariaDB / MySQL การทำคลัสเตอร์อัตโนมัติสำหรับข้อมูลเพิ่มเติมเกี่ยวกับแพ็คเกจที่ติดตั้งและตัวเลือกการปรับแต่งที่พร้อมใช้งาน

การติดตั้งด้วยตนเอง

หากคุณต้องการกำหนดค่าการจำลองแบบ Master-Slave ด้วยตนเองเพื่อรับตัวจำลอง Slave เพิ่มเติมหรือระบุการกำหนดค่าที่กำหนดเองบางอย่าง โปรดปฏิบัติตามคำแนะนำด้านล่าง

เคล็ดลับ : คำแนะนำด้านล่างนี้เหมาะสำหรับเซิร์ฟเวอร์ฐานข้อมูล MySQL และ MariaDB อย่างยิ่ง

ก่อนอื่นต้องสร้าง Env 2 ตัวใน Ruk-Com สำหรับฐานข้อมูล master และฐานข้อมูล slave

  1. เข้าสู่ระบบเข้าสู่แดชบอร์ด Ruk-Com แล้วคลิกปุ่ม New Environment

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  2. ใน Env Topology wizard ให้เลือก MariaDB (หรือ MySQL) เป็นฐานข้อมูลที่คุณต้องการใช้ ตั้งค่าลิมิต cloudlet และพิมพ์ชื่อของ Env ตัวแรกของคุณตัวอย่างเช่น masterbase

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

    รอสักครู่เพื่อให้ Env ถูกสร้างขึ้น

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  3. ในทำนองเดียวกันให้สร้าง Env ขึ้นมาใหม่ด้วย MariaDB หรือเพียงแค่โคลน มาตั้งชื่อว่า slavebase จะอยู่ใน hardnode อื่นซึ่งมีความปลอดภัยและเชื่อถือได้มากขึ้นสำหรับการจัดเก็บข้อมูล

    ตอนนี้คุณมี Env 2 ตัวที่เหมือนกันกับทั้งสองฐานข้อมูล

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

มากำหนดค่า master base กันเลย

  1. คลิกปุ่ม Config สำหรับฐานข้อมูล master

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  2. ไปที่ไฟล์ my.cnf และเพิ่มคุณสมบัติต่อไปนี้ตามที่แสดงด้านล่าง:
server-id = 1
log-bin = mysql-bin
binlog-format = mixed

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

เราใช้รูปแบบ “mixed” binlog (binlog-format = mixed) เพื่อให้สามารถจำลองการทำงานด้วย foreign keys ได้

หมายเหตุ : อย่าใช้รูปแบบ “statement” binlog มิฉะนั้นคุณจะได้รับข้อผิดพลาดในภายหลัง!

  1. Save การเปลี่ยนแปลงและ Restart MariaDB เพื่อใช้พารามิเตอร์ที่กำหนดค่าใหม่

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  2. คลิกปุ่ม Open in Browser สำหรับ MariaDB, Ruk-Com จะส่งอีเมลถึงคุณพร้อมข้อมูลรับรองไปยังฐานข้อมูลเพื่อเข้าสู่ระบบโดยใช้ข้อมูลรับรองเหล่านี้
  3. ไปที่แท็บ User accounts แล้วคลิก Add user account

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  4. ระบุ name และ password สำหรับผู้ใช้การจำลองแบบ slave

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

ตอนนี้เลื่อนลงและทำติ๊กเครื่องหมายที่ replication client และ replication slave ตรงส่วนของ administration privileges

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

คลิก Go ที่อยู่ด้านล่างของหน้า

  1. สลับไปที่แท็บ Status เพื่อให้แน่ใจว่าการจำลองถูกกำหนดค่าอย่างถูกต้อง

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

ให้ความสนใจกับค่า Log File และ Position เนื่องจากจะต้องใช้ในภายหลังเพื่อตั้งค่าฐานข้อมูล Slave

กลับไปที่แดชบอร์ด Ruk-Com และกำหนดค่าฐานข้อมูล Slave

  1. คลิกปุ่ม Config สำหรับ Slavebase Env

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  2. ไปที่ไฟล์ my.cnf และเพิ่มสตริงต่อไปนี้:
server-id = 2
slave-skip-errors = all

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

เราอนุญาตให้ slave base ข้ามข้อผิดพลาดทั้งหมดจาก master (slave-skip-errors = all) เพื่อไม่ให้หยุดการทำงานของ normal slave ในกรณีที่เกิดข้อผิดพลาดบน master base

หมายเหตุ : ไม่แนะนำให้ใช้การข้ามนี้ในระหว่างขั้นตอนการพัฒนาเนื่องจากช่วยในการค้นหาและแก้ไขข้อบกพร่อง อย่างไรก็ตามในการใช้งานจริง (เมื่อโค้ดของคุณได้รับการทดสอบแล้ว) จะช่วยหลีกเลี่ยงการไม่ซิงโครไนซ์สำหรับปัญหาเล็กน้อยใน master node

  1. จากนั้นเปิดไฟล์ /etc/phpMyAdmin/กำหนดค่า.inc.php และใส่ต่อท้ายด้วยโค้ดถัดไป:
$cfg['AllowArbitraryServer'] = true;

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

  1. Save การเปลี่ยนแปลงและ Restart เซิร์ฟเวอร์ฐานข้อมูล slave เพื่อใช้พารามิเตอร์คอนฟิกูเรชันใหม่

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  2. มากำหนดค่าเซิร์ฟเวอร์ฐานข้อมูล slave ผ่านเว็บ SSHclient แบบบิวท์อิน เชื่อมต่อกับฐานข้อมูลของคุณโดยใช้ข้อมูลประจำตัวจากอีเมลที่ได้รับหลังจากการสร้างโหนด
mysql -u root -p


ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

  1. ให้รายละเอียดการจำลองแบบของ master
CHANGE MASTER TO
MASTER_HOST='node275500-masterbase.jelastic.com',
MASTER_USER='slave',
MASTER_PASSWORD='passw0rd',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=853;

อย่าลืมแทนที่ค่าของตัวเลือกในตัวอย่างด้านบนด้วยข้อมูลที่ถูกต้อง:

  • MASTER_HOST - URL หรือ IP การจำลองแบบของ master
  • MASTER_USER - ผู้ใช้การจำลองแบบ
  • MASTER_PASSWORD - รหัสผ่านของผู้ใช้การจำลอง
  • MASTER_LOG_FILE – ไฟล์ log ของ master (ดูขั้นตอนสุดท้ายของส่วนการกำหนดค่า master)
  • MASTER_LOG_POS – ตำแหน่ง log ของ master (ดูขั้นตอนสุดท้ายของส่วนการกำหนดค่า master)


ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

  1. ตอนนี้คุณสามารถเริ่มการจำลองแบบ slave ด้วยคำสั่งที่เหมาะสม:
start slave;


ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

เคล็ดลับ : หากคุณต้องการให้แน่ใจว่าทุกอย่างได้รับการกำหนดค่าอย่างถูกต้องให้เข้าสู่ระบบในส่วนของฐานข้อมูล slave สำหรับแอดมิน และไปที่แท็บ Status

ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

เราต้องตรวจสอบให้แน่ใจว่าการจำลองแบบ master-slave ใช้งานได้กับฐานข้อมูลของเราแล้ว

  1. มาสร้างฐานข้อมูลใหม่ (เช่น Ruk-Com) ใน master base ของเรา

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS
  2. ไปที่ slave base และคุณจะเห็นว่าฐานข้อมูลใหม่ถูกจำลองสำเร็จแล้ว

    ภาพประกอบขั้นตอนการใช้งาน Ruk-Com Cloud PaaS

นี่คือ 2 ตัวอย่างของการเชื่อมต่อกับฐานข้อมูล master และฐานข้อมูล slave จากแอปพลิเคชัน Java และ PHP

  1. ตัวอย่างเช่นคุณสามารถดูโค้ดของแอปพลิเคชัน Java ของคุณซึ่งเชื่อมต่อกับฐานข้อมูล master และฐานข้อมูล slave Database_กำหนดค่า.cfg:
master_host=jdbc:mysql://mariadb-master-host/mysql
master_username=root
master_password=abcABC123

slave_host=jdbc:mysql://mariadb-slave-host/mysql
slave_username=root
slave_password=abcABC123

driver=com.mysql.jdbc.Driver

Dbmanager.java:

package com.jelastic.test;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DbManager {

    private final static String createDatabase = "CREATE SCHEMA IF NOT EXISTS jelastic";
    private final static String showDatabases = "SHOW DATABASES";

    public Connection createMasterConnection() throws IOException, ClassNotFoundException, SQLException {
       Connection masterConnection;
       Properties prop = new Properties();
       prop.load(new FileInputStream(System.getProperty("user.home") + "/database_config.cfg"));
       String master_host = prop.getProperty("master_host").toString();
       String master_username = prop.getProperty("master_username").toString();
       String master_password = prop.getProperty("master_password").toString();
       String driver = prop.getProperty("driver").toString();

       Class.forName(driver);
       masterConnection = DriverManager.getConnection(master_host, master_username, master_password);
       return masterConnection;
    }

    public Connection createSlaveConnection() throws IOException, ClassNotFoundException, SQLException {
       Connection slaveConnection;
       Properties prop = new Properties();
       prop.load(new FileInputStream(System.getProperty("user.home") + "/database_config.cfg"));
       String slave_host = prop.getProperty("slave_host").toString();
       String slave_username = prop.getProperty("slave_username").toString();
       String slave_password = prop.getProperty("slave_password").toString();
       String driver = prop.getProperty("driver").toString();

       Class.forName(driver);
       slaveConnection = DriverManager.getConnection(slave_host, slave_username, slave_password);
       return slaveConnection;
    }

    public boolean runSqlStatementOnMaster() {
       boolean execute = false;
       Statement statement = null;
       try {
           statement = createMasterConnection().createStatement();
           execute = statement.execute(createDatabase);
       } catch (IOException ex) {
         Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
       } catch (ClassNotFoundException ex) {
         Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
       } catch (SQLException ex) {
           ex.printStackTrace();
       } finally {
           if (statement != null) {
               try {
                   statement.close();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
           }
       }
       return execute;
    }

    public List<String> runSqlStatementOnSlave() {
       List<String> stringList = new ArrayList<String>();
       Statement statement = null;
       ResultSet resultSet = null;
       try {
           statement = createSlaveConnection().createStatement();
           resultSet = statement.executeQuery(showDatabases);
           while (resultSet.next()) {
               stringList.add(resultSet.getString(1));
           }
       } catch (IOException ex) {
         Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
       } catch (ClassNotFoundException ex) {
         Logger.getLogger(DbManager.class.getName()).log(Level.SEVERE, null, ex);
       } catch (SQLException ex) {
           ex.printStackTrace();
       } finally {
           if (resultSet != null) {
               try {
                   resultSet.close();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
           }
           if (statement != null) {
               try {
                   statement.close();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
           }
       }
       return stringList;
    }
}
  1. การเชื่อมต่อกับฐานข้อมูล master และฐานข้อมูล slave สำหรับแอปพลิเคชัน PHP
<?php
/* Master settings */
$master_server = "xx.xxx.x.xx";
$master_username = "root";
$master_password = "abcABC123";

/* Slave settings */
$slave_server = "xx.xxx.x.xx";
$slave_username = "root";
$slave_password = "abcABC123";

$link_to_master = mysqli_connect(
$master_server,
$master_username,
$master_password,
'mysql');

if (!$link_to_master) {
printf("Unable to connect master database server. Error: %s\n", mysqli_connect_error());
exit;
}

$link_to_slave = mysqli_connect(
$slave_server,
$slave_username,
$slave_password,
'mysql');

if (!$link_to_slave) {
printf("Unable to connect slave database server. Error: %s\n", mysqli_connect_error());
exit;
}

print("
Creating database with name Jelastic on Master node ");

$result = mysqli_query($link_to_master, 'CREATE DATABASE JelasticX');

sleep (3);

print("
Checking if created database was replciated to slave ");

if ($result = mysqli_query($link_to_slave, 'SHOW DATABASES LIKE "JelasticX"')) {
$result_text = mysqli_fetch_array($result);
print ("
Replicated database is ".$result_text[0]);
}

mysqli_close($link_to_master);
mysqli_close($link_to_slave);
?>

ตอนนี้คุณมีการจำลองฐานข้อมูลของคุณเองในระบบคลาวด์แล้ว ขอให้สนุกไปกับมัน!