实现AB机功能我需要做什么??
1. 既然要实现一个功能,则就需要知道这个功能的原理。或者说知道他是在做什么,要干什么?(我们要做的就是把一个主机的快照从一个一体机中拷贝到另一个一体机中)
那么我们是不是就需要清楚这个数据我们是怎么用的?是被分为了几层?和什么东西有关联?通过什么找到这个数据或者我们下一次需要同步的数据?数据有几种类型?同步方式有几种类型?数据类型的不同和同步方式的不同会不会有什么差异??他们的共同点在哪儿?在同步的时候我们需要注意什么??
首先我们的备份点使用是:通过主机找到他的备份点,而这个备份点还属于主机快照级别,然后我们通过主机快照找到他对应的磁盘快照,而后通过磁盘快照找到,快照存储级别,通过快照存储级别就能找到真正的快照文件存放在哪儿!从而找到我们需要使用的数据,也就是说数据被分为了5层?主机--》主机快照--》磁盘快照--》磁盘快照存储--》快照文件,由于我们的快照文件需要精确到时间,因此我们在同步的时候需要远端一体机中存放的数据“复制一遍”到本地的一体机中。快照文件分为两种类型,qcow和cdp类型,qcow是一个时刻的备份点,cdp是一段时间的备份段,那么cdp和qcow的差异是什么??我们的同步方式也有两种,一种是间隔同步,一种是持续同步?那么同步方式和快照文件类型的不同组合会有什么差异呢??
间隔: 就是计划时需要间隔一段时间执行的,就是这个执行完了就结束了,而间隔一段时间后继续执行(计划层面控制??)
持续: 计划一经执行,再不出意外的情况下会一直执行,不会停止。
qcow 间隔 --》qcow
qcow 持续 --》qcow
cdp 间隔 --》qcow
cdp 持续 --》cdp
有什么特殊的地方吗?
1. 由于cdp必须是持续进行备份的,而对于间隔类型同步方式,备份后的快照只能为qcow类型的,那么这个需要同步的备份点该怎么找呢??首先:第一次的时候,我们会同步cdp的一个时刻cdp最后一个时刻的点到本地中,当下一次的时候,我们需要拿到这次备份的时刻点找到下一个时刻点??还是只去同步最后一个时刻点,对于间隔同步,都是去拿最后一个时刻点
2. 对于间隔类型同步,我们每一次就是找最后一个, 而持续类型,只有第一次是找最后一个,后面都是找下一个。
3. 对于源是cdp快照文件,同步方式是持续同步这种类型,我们在第一次的时候是拿到cdp的最后一个时刻点,而后进行同步,此时是需要同步成qcow类型文件,而在下一次同步的时候,我们需要找到第一次同步的下一个时刻点进行同步,存储为cdp类型文件。由于在空间回收的时候,会将cdp快照分为一个qcow类型文件和cdp类型文件,而这个时候因为两个的开始时刻是一样的,所以我们可能只能找到为qcow类型文件的备份点,而导致反复同步改时刻,因此需要特殊处理一下。在同步进行的时候,需要锁住在同步的快照点。
2. 在知道了这个原理之后,我们就要想该怎么实现这个功能???
我们需要同步5层的数据
按照以前的逻辑来看:
我们在创建远程容灾计划的时候会先把主机的信息给同步过来,这个不改。
那么剩下的我们怎么同步呢???
首先从数据的关系来看,对于普通的客户端
一个主机快照对应多个磁盘快照
一个磁盘快照对应一个磁盘快照存储?
一个磁盘快照存储对应一个qcow文件?
那么我们就可以分为两层
就是主机快照算作一层任务,在这一层下面,可以对应多个子任务(同步存储快照,磁盘快照存储,快照文件)
现在的cdp快照是怎么样的?
1. 所有的子任务结束了主任务才结束。
2. 对于 cdp 和 持续类型的任务 该怎么同步呢? 由于是持续,就直接去找有没有新的storage生成,没有就结束,
同步逻辑:
while True:
for schedule in remotebackupschedule:
if schedule not in _is_running:
根据计划创建一个远程灾备任务
create_remote_backup_task(schedule)
_is_running.append(schedule)
def create_remote_backup_task(schedule):
while True:
remote_task = load_remote_task()
if remote_task:
remote_task.main_logic()
real_create_remote_backup_task()
def real_create_remote_backup_task()
last_host_snapshot_info, last_host_snapshot_timestamp = query_last_sync_hostsnapshot_info() # 查找同步的本地的主机快照信息
new_host_snapshot_info, new_host_snapshot_timestamp = query_new_host_snapshot(host, last_host_snapshot.remote_id,
last_host_snapshot_timestamp) # 到A端找最新的主机快照信息
create_remote_backup_task(last_host_snapshot_info, new_host_snapshot_info)
create_local_host_snapshot()
create_disk_snapshots()
create_storages()
def main_logic():
while True:
sub_tasks = create_or_load_sub_tasks()
for sub_task in sub_tasks:
if sub_task in runing_sub_task:
continue
runing_sub_task.append(sub_task)
new_task = RemoteBackupSubTaskThreading(sub_task)
new_task.start()
if is_cdp() and (not query_is_end(sub_task)):
create_new_sub_task(sub_task)
def create_or_load_sub_tasks(self):
sub_tasks = list()
for disk_snapshot_level in currnt_host_snapshot_level.query_disk_snapshot():
sub_task = load_remote_backup_sub_task(disk_snapshot_level)
if sub_task:
sub_tasks.append(sub_task)
continue
prev_hostsnapshot = query_prev_host_snapshot(currnt_host_snapshot_level.host)
prev_disksnapshot = prev_hostsnapshot.query_disk_snapshot(native_guid)
prev_storage = prev_disksnapshot.last_storage
prev_sub_task = query_sub_task(prev_storage) # 同步这个storage的sub task
prev_remote_storage_ident, prev_remote_storage_timestamp = prev_sub_task.fetch_info
create_remote_subtask_on_A(task_uuid_on_A, current_remote_disksnapshot,
current_remote_timestamp(主机快照时刻),
prev_remote_storage_ident,
prev_remote_storage_timestamp)
sub_task = create_sub_task(disk_snapshot_level.last_storage, task_uuid_on_A)
sub_task.append(sub_task)
return sub_tasks
1. 在同步的时候,会去打开快照,由于现在打开快照和之前的方式并不一样,所以remotess层是不是会进行一个修改,传过去一个handle?,还有怎么去通信呢?本地??还是远端??由于remotess是通过命令行的方式启动的,所以会启用本地的remotess,从代码得逻辑来看,也就是主节点执行,那么调用主节点的ImageService没有问题?那么是不是可以进行远端通信呢?看起来没有必要,因为远端通信的话,是不是也是需要调到主节点的ImageService呢?所以就直接在本地执行(主节点)而对于A端,是通过data_quening通信,那么是不是可以随便在那个节点?不过在B端拿数据的时候,肯定需要知道是在那个节点上拿数据进行通信的。