MYSQL集群双主双备双VIP读写分离高可用优化版KEEPALIVED

版权声明:本文为博主原创文章,未经博主允许可以转载。 https://blog.csdn.net/ccagy/article/details/82255481

规划:

主1:172.16.108.71 ---》从 1:172.16.108.73   同步

      |主1与主2双向同步

主2:172.16.108.72--》从2:172.16.108.74 同步

主2与从2是一个紧急备用,正常情况下不投入使用

VIP1:写入172.16.108.110

VIP2:读取172.16.108.111 

主机1

my.cnf

[client]
#password       = your_password
port            = 3306
socket          = /tmp/mysql.sock

# Here follows entries for some specific programs
# The MySQL server
[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
skip-locking
key_buffer_size = 384M
max_allowed_packet = 128M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8

log-bin=mysql-bin
binlog-do-db=tx
server-id       = 1
auto-increment-increment=2
auto-increment-offset=1
log-slave-updates

[mysqldump]
quick
max_allowed_packet = 128M


[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout
主机2

[client]
#password       = your_password
port            = 3306
socket          = /tmp/mysql.sock

# Here follows entries for some specific programs
server_id=2
# The MySQL server
[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
skip-locking
key_buffer_size = 384M
max_allowed_packet = 128M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
server_id=2

# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8

# binary logging is required for replication
log-bin=mysql-bin
binlog-do-db=tx
server-id       = 2
auto-increment-increment=2
auto-increment-offset=2
log-slave-updates

[mysqldump]
quick
max_allowed_packet = 128M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

手下1同步主1

[client]
#password       = your_password
port            = 3306
socket          = /tmp/mysql.sock

# Here follows entries for some specific programs

# The MySQL server
[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
skip-locking
key_buffer_size = 384M
max_allowed_packet = 128M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8

log-bin=mysql-bin

server-id       = 3

[mysqldump]
quick
max_allowed_packet = 128M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout
 

手下2同步主2


[client]
#password       = your_password
port            = 3306
socket          = /tmp/mysql.sock

# Here follows entries for some specific programs

# The MySQL server
[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
skip-locking
key_buffer_size = 384M
max_allowed_packet = 128M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8

log-bin=mysql-bin

server-id       = 4

[mysqldump]
quick
max_allowed_packet = 128M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

MYSQL集群脚本

GRANT REPLICATION SLAVE ON *.* TO 'root' @'%' IDENTIFIED BY '1';
SHOW MASTER STATUS;

STOP SLAVE;

CHANGE MASTER TO MASTER_HOST='172.16.108.72',MASTER_USER='root',MASTER_PASSWORD='1',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=106;

START SLAVE;
        
SHOW SLAVE STATUS
        
SHOW MASTER STATUS;

主机的keepalived

[root@k8s1 ~]# vim /etc/keepalived/keepalived.conf 

! Configuration File for keepalived

global_defs {
   notification_email {
   root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1                    #邮件服务器的地址
   smtp_connect_timeout 30
   router_id k8s1                      #主调度器的主机名
   vrrp_mcast_group4 224.26.1.1             #发送心跳信息的组播地址

}

vrrp_instance VI_1 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 66                    #虚拟路由的ID
    nopreempt                               #设置虚拟ip不被抢占
    priority 90                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.99
    }
}

vrrp_instance VI_2 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 6                   #虚拟路由的ID
    # nopreempt                               #注释后要抢占
    priority 90                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.110
    }
}


virtual_server 172.16.108.110 3306 {
   delay_loop 2
   lb_algo rr
   lb_kind DR
   persistence_timeout 60
   protocol TCP
   real_server 172.16.108.71 3306 {
       weight 5
       #notify_down     /etc/keepalived/mysql.sh
       TCP_CHECK {
            connect_timeout 2
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
       }

   }

主机2的keealived

[root@k8s2 ~]# vim /etc/keepalived/keepalived.conf 

! Configuration File for keepalived

global_defs {
   notification_email {
   root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1                    #邮件服务器的地址
   smtp_connect_timeout 30
   router_id k8s2                      #主调度器的主机名
   vrrp_mcast_group4 224.26.1.1             #发送心跳信息的组播地址

}

vrrp_instance VI_1 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 66                    #虚拟路由的ID
    nopreempt                               #设置虚拟ip不被抢占
    priority 90                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.99
    }
}


vrrp_instance VI_2 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 6                    #虚拟路由的ID
    nopreempt                                #设置虚拟ip不被抢占
    priority 10                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.110
    }
}

virtual_server 172.16.108.110 3306 {
   delay_loop 2
   lb_algo rr
   lb_kind DR
   persistence_timeout 60
   protocol TCP
   real_server 172.16.108.72 3306 {
       weight 3
       #notify_down     /etc/keepalived/mysql.sh
       TCP_CHECK {
            connect_timeout 2
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
       }

   }

主1的手下1的keepalived

! Configuration File for keepalived

global_defs {
   notification_email {
   root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1                    #邮件服务器的地址
   smtp_connect_timeout 30
   router_id k8s3                      #主调度器的主机名
   vrrp_mcast_group4 224.26.1.1             #发送心跳信息的组播地址

}
vrrp_script chk_mysql {
        script "/root/chk.sh"
        interval 2
}
vrrp_instance VI_1 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 66                    #虚拟路由的ID
    nopreempt                               #设置虚拟ip不被抢占
    priority 90                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.99
    }
}

vrrp_instance VI_2 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 7                   #虚拟路由的ID
    #nopreempt                               #抢占VIP
    priority 90                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    track_script {
        chk_mysql
    }
    virtual_ipaddress {
        172.16.108.111
    }
}

主机2的手下2

! Configuration File for keepalived

global_defs {
   notification_email {
   root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1                    #邮件服务器的地址
   smtp_connect_timeout 30
   router_id k8s3                      #主调度器的主机名
   vrrp_mcast_group4 224.26.1.1             #发送心跳信息的组播地址

}

vrrp_instance VI_1 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 66                    #虚拟路由的ID
    nopreempt                               #设置虚拟ip不被抢占
    priority 90                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.99
    }
}

vrrp_instance VI_2 {
    state BACKUP                            #主调度器的初始角色
    interface enp0s3
    virtual_router_id 7                    #虚拟路由的ID
    nopreempt                               #设置虚拟ip不被抢占
    priority 10                           #主调度器的选举优先级
    advert_int 1
    authentication {
        auth_type PASS                      #集群主机的认证方式
        auth_pass 123456                    #密钥,最长8位
    }
    virtual_ipaddress {
        172.16.108.111
    }
}

主机1的检查脚本,避免主机1挂了从1还在工作,产生信息孤岛。

/root/chk.sh

#/bin/sh
. /etc/init.d/functions

echo "Up"
count=0
for loop in 1 2 3
do
num=`echo -n "\n"|telnet 172.16.108.71 3306|grep Connected|wc -l`
if [ $num -eq 1 ]
then
      action "network is open." /bin/true
      systemctl start mysqld
      count=0
      echo "$count"
else
       if [ $count == 2 ]
       then
            action "network is closed." /bin/false
            systemctl stop mysqld
            echo 'mysql stop...'
       else
            count=$((count+1))
       fi
fi
done

-----

c#性能测试代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using MySql.Data;
using MySql.Data.MySqlClient;
namespace MYSQL_TEST
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        Thread th;
        private void button1_Click(object sender, EventArgs e)
        {
            th = new Thread(insert);
            th.Start();
            Thread th1 = new Thread(reada);
            th1.Start();

            Thread th2 = new Thread(readb);
            th2.Start();

            Thread th3 = new Thread(readc);
            th3.Start();

            Thread th4 = new Thread(readd);
            th4.Start();
        }

        private void insert()
        {
            while (true)
            {
                MySqlConnection sqlCnn = new MySqlConnection();
                sqlCnn.ConnectionString = "Database=tx;Data Source=172.16.108.110;Port=3306;User Id=root;Password=1;Charset=utf8;";
                MySqlCommand sqlCmd = new MySqlCommand();
                sqlCmd.Connection = sqlCnn;
                sqlCmd.CommandText = "INSERT INTO ttxx(NAME) VALUES('dfhsdjkhfjkasdhfjkhsdjk');";

                try
                {
                    sqlCnn.Open();
                    int row = sqlCmd.ExecuteNonQuery();
                    sqlCnn.Close();
                }
                catch (Exception ex)
                {
                    textBox1.Text += "插入失败:"+ex.Message+"\r\n";
                    sqlCnn.Close();
                }
                Thread.Sleep(Convert.ToInt32(textBox2.Text));
            }

        }


        private void reada()
        {
            while (true)
            {
                MySqlConnection sqlCnn = new MySqlConnection();
                sqlCnn.ConnectionString = "Database=tx;Data Source=172.16.108.71;Port=3306;User Id=root;Password=1;Charset=utf8;";
                MySqlCommand sqlCmd = new MySqlCommand();
                sqlCmd.Connection = sqlCnn;
                sqlCmd.CommandText = "select count(*) from ttxx;";

                try
                {
                    sqlCnn.Open();
                    int row = Convert.ToInt32(sqlCmd.ExecuteScalar());
                    sqlCnn.Close();
                    lbla.Text = row.ToString() + "条数据";
                    label1.BackColor = Color.Green;
                }
                catch (Exception ex)
                {
                    textBox1.Text += "读取71失败:" + ex.Message + "\r\n";
                    label1.BackColor = Color.Red;
                    sqlCnn.Close();
                }
                Thread.Sleep(50);
            }
        }
        private void readb()
        {
            while (true)
            {
                MySqlConnection sqlCnn = new MySqlConnection();
                sqlCnn.ConnectionString = "Database=tx;Data Source=172.16.108.73;Port=3306;User Id=root;Password=1;Charset=utf8;";
                MySqlCommand sqlCmd = new MySqlCommand();
                sqlCmd.Connection = sqlCnn;
                sqlCmd.CommandText = "select count(*) from ttxx;";

                try
                {
                    sqlCnn.Open();
                    int row = Convert.ToInt32(sqlCmd.ExecuteScalar());
                    sqlCnn.Close();
                    lblb.Text = row.ToString() + "条数据";
                    label2.BackColor = Color.Green;
                }
                catch (Exception ex)
                {
                    textBox1.Text += "读取73失败:" + ex.Message + "\r\n";
                    label2.BackColor = Color.Red;
                    sqlCnn.Close();
                }
                Thread.Sleep(50);
            }
        }
        private void readc()
        {
            while (true)
            {
                MySqlConnection sqlCnn = new MySqlConnection();
                sqlCnn.ConnectionString = "Database=tx;Data Source=172.16.108.72;Port=3306;User Id=root;Password=1;Charset=utf8;";
                MySqlCommand sqlCmd = new MySqlCommand();
                sqlCmd.Connection = sqlCnn;
                sqlCmd.CommandText = "select count(*) from ttxx;";

                try
                {
                    sqlCnn.Open();
                    int row = Convert.ToInt32(sqlCmd.ExecuteScalar());
                    sqlCnn.Close();
                    lblc.Text = row.ToString() + "条数据";
                    label3.BackColor = Color.Green;
                }
                catch (Exception ex)
                {
                    textBox1.Text += "读取72失败:" + ex.Message + "\r\n";
                    label3.BackColor = Color.Red;
                    sqlCnn.Close();
                }
                Thread.Sleep(50);
            }
        }
        private void readd()
        {
            while (true)
            {
                MySqlConnection sqlCnn = new MySqlConnection();
                sqlCnn.ConnectionString = "Database=tx;Data Source=172.16.108.92;Port=3306;User Id=root;Password=1;Charset=utf8;";
                MySqlCommand sqlCmd = new MySqlCommand();
                sqlCmd.Connection = sqlCnn;
                sqlCmd.CommandText = "select count(*) from ttxx;";

                try
                {
                    sqlCnn.Open();
                    int row = Convert.ToInt32(sqlCmd.ExecuteScalar());
                    sqlCnn.Close();
                    lbld.Text = row.ToString() + "条数据";
                    label4.BackColor = Color.Green;
                }
                catch (Exception ex)
                {
                    textBox1.Text += "读取92失败:" + ex.Message + "\r\n";
                    label4.BackColor = Color.Red;
                    sqlCnn.Close();
                }
                Thread.Sleep(50);
                if (textBox1.Text.Length > 1000) textBox1.Text = "";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {

            try
            {
                th.Abort();
            }
            catch (Exception)
            {

                th.Abort();
            }
           
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/ccagy/article/details/82255481
今日推荐