【Otter】关于otter双A模式的一点疑问

何为双A模式:可以简单理解为mysql的双主模式,互为主从
具体可参考:https://github.com/alibaba/otter/wiki/Manager配置介绍


官方博客的配置方法:

双A同步相比于双向同步,整个配置主要是一些参数上有变化,具体步骤:

配置一个channel 
【Otter】关于otter双A模式的一点疑问_第1张图片
配置两个pipeline
【Otter】关于otter双A模式的一点疑问_第2张图片 * 注意:除了需要定义一个主站点外,需要在高级设置中将一个pipeline的“支持DDL”设置为false,另一个设置为true,否则将提示“一个channel中只允许开启单向ddl同步!”错误 每个pipeline各自配置canal,定义映射关系

背景:
111<->112 双A模式

111->112_canal:111 同步数据至112 
主站点:true
支持ddl同步:    关闭     
跳过ddl异常:    开启

112->111_canal:112同步数据至111
主站点:flase
支持ddl同步:    开启
跳过ddl异常:    开启

在以上的背景下
疑问一:数据的增删查改都没问题,但是当在111上 执行create table/Truncate 这类DDL语句后,不会同步到112上,反之在112上执行可以同步至111,因为支持ddl同步这个参数的原因

解决办法:
待续

疑问二:当表没有主键约束时,在非主站点上执行insert会重复插入一条如:
非主站点上执行:
mysql> insert into test3 values(5);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test3;
+------+
| id |
+------+
| 4 |
| 5 |
| 5 |
+------+
3 rows in set (0.00 sec)

主站点上:
mysql> select * from test3;
+------+
| id |
+------+
| 4 |
| 5 |
+------+
2 rows in set (0.00 sec)
同步至主站点了,但是非主站点会再插入一遍
原因:otter设计的单向回环
【Otter】关于otter双A模式的一点疑问_第3张图片

思路:最终一致性

适用场景: A地和B地数据不对等,比如A地为主,写入量比较高,B地有少量的数据写入

单向回环流程:(比如图中以HZ为trusted source站点)

us->hz同步的数据,会再次进入hz->us队列,形成一次单向回环 hz->us同步的数据,不会进入us->hz队列(回环终止,保证不进入死循环)
解决办法:设计表都带上自增主键


疑问三:如果两边同时插入一条数据,自增id怎么办?
#coding=utf-8
import threading
from time import ctime,sleep
import MySQLdb
import random ###导入模块
def insert(ip,num):
   conn=MySQLdb.connect(user="root",passwd="ESBecs00",db="mydb",port=3306,host=ip,charset="utf8")
   cursor =conn.cursor() ###获得链接游标
   sql ="insert into admin(role_id) values (%s);commit;" % num ###sql语句
   n=cursor.execute(sql) ###执行sql
   row=cursor.fetchall() ###fetchall()活得所有返回结果,fetchone()活得一条返回结果
   print row
   cursor.close() ###关闭游标
   conn.close() ###关闭连接

threads = []

t1 = threading.Thread(target=insert,args=('10.32.7.111',88))
threads.append(t1)
 
t2 = threading.Thread(target=insert,args=('10.32.7.112',888))
threads.append(t2)

if __name__ == '__main__':
    for t in threads:
        t.setDaemon(True)
        t.start()

    for t in threads:
        t.join()

    print "all over %s" %ctime()
#insert('10.32.7.111',88)

该段代码模拟的是同时往主站点和非主站点插入一条数据!
[root@DB-22 dbaadmin]# python test.py 
()
()
all over Mon Jul 31 16:44:27 2017


结果
mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 8 | 77 |
| 9 | 777 |
| 11 | 99 |
| 12 | 999 |
| 16 | 888 |    ---可以看到,主站点丢失,未插入!
+----+---------+
5 rows in set (0.00 sec)


在github上otter数据库入库算法》部分看到这样一段话:合并算法执行后,单pk主键只有一条记录,减少并行load算法的复杂性(比如batch合并,并行/串行等处理)
因为并发插入之间的时间间隔非常短,短于同步之间的延迟,在主副站点分别插入后是同一条pk建,并且副站点后插入,那么副站点是最新副本集也就是trust 点,副站点数据覆盖主站点数据,《otter数据一致性》详解!

解决办法:参考官方双a的做法,设置步长和起始值
修改两台的步长 mysql> show global variables like '%auto_increment_increment%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 2 |
+--------------------------+-------+

mysql> show global variables like '%auto_increment_increment%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
+--------------------------+-------+
再次测试 [root@DB-22 dbaadmin]# python test.py 
()
()
all over Mon Jul 31 17:54:10 2017
[root@DB-22 dbaadmin]# python test.py 
()
()
all over Mon Jul 31 17:54:21 2017



mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 28 |     111 |
+----+---------+
1 row in set (0.00 sec)


mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 28 |     111 |
| 29 |     888 |
| 30 |      88 |
+----+---------+
3 rows in set (0.00 sec)


mysql> select * from admin;
+----+---------+
| id | role_id |
+----+---------+
| 28 |     111 |
| 29 |     888 |
| 30 |      88 |
| 31 |     888 |
| 32 |      88 |
+----+---------+
5 rows in set (0.00 sec)






来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29096438/viewspace-2142597/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29096438/viewspace-2142597/

你可能感兴趣的:(【Otter】关于otter双A模式的一点疑问)