为了在根源上解决用户在外部邮箱操作导致搬家邮件重复的问题说明
一、邮件导出层面避免重复
在我们邮件搬家最开始的版本中,已经对邮件在外部邮箱导出时做了重复判断处理,也就是导出成功的邮件不再重复导出,保证导入不重复。下面我们会拿Gmail邮局作为例子,实际上这个适用于所有邮局。
比如您之前使用aaa@gmail.com的gmail邮箱,现在要把它的邮件数据迁移到我们系统的aaa@ourserver.com这个邮箱,则总体的逻辑见下图:
比如,您Gmail邮局中aaa@gmail.com邮箱有2封邮件,我们搬家服务器上的程序从gmail获取到这两封邮件的唯一id,这里假设唯一id分别是1和2。这两封邮件通过我们搬家服务器存储到我们的邮件存储中后,我们也会把这两封对应的从Gmail获取到的id值存入数据库。在本例中,我们对gmail邮局的两封邮件搬家成功后,将这两封邮件的唯一id也存入搬家数据库。
搬家成功后,您gmail邮箱又收到第三封新的邮件,为了能够将最新的第三封邮件搬入我们邮局,您可以重试搬家(或者系统自动重试),可见下图:
在上图重试搬家中,我们搬家服务器从Gmail邮局获取到三封邮件id,分别是之前搬家成功的id:1和2,以及gmail最新收到的邮件id:3。由于id:1和2对应的邮件之前已成功搬家,则我们系统不会再从gmail下载(导出)这两封邮件内容,只会导出最新的第三封邮件内容,当然也只会将第三封邮件内容导入的我们的邮件存储中。这样在导出阶段,我们做到了避免用户邮箱重复导出导入的问题。
二、邮件导入层面避免重复
我们在2021-01-14,搬家过程进一步优化,在导入过程中进行去重,避免邮件重复导入。
所要解决的问题请见下图:
比如您将上例中新收到的第三封邮件下载到您本地电脑上(上图第一步),然后您将刚下载的第三封邮件从Gmail邮局删除(上图第二步)。在以后工作中,您又将下载的第三封邮件上传到Gmail邮局(上图第三步)。由于新上传的邮件在Gmail邮局中认为是新的一封邮件,所以这封邮件的id将会记为一个新的唯一id值,比如为4(上图第四步)。这样同样三封搬家成功的邮件id值改变了。此外,邮件移动到其他邮件箱,然后再移动回来之类操作都会造成相同邮件在Gmail中唯一id发生改变的情况。
这样就会导致您的邮件在搬家中重复,如下图演示:
之前我们论述了,您将第三封邮件下载到本地后删除,随后再次导入,Gmail的邮件id发生改变。之后重试搬家时,Gmail会将最新的id列表:1,2,4返回给我们,由于id为1和2的邮件已经搬家成功自动忽略外,id为4的邮件不在我们邮件搬家数据库中,所以我们会将id为4的邮件搬家导入到我们的邮件存储中。但是之前我们已经迁移过id为3的邮件,而id为3的邮件内容和id为4的邮件是一样的,所以您在我们邮局系统中将会看到两封一模一样的邮件。
为了解决这样的问题,我们再次优化了搬家逻辑,改成了如下方式:
我们回到最初,您的aaa@gmail.com中有两封邮件需要搬家到我们系统,在搬家成功后,我们会记录从Gmail邮局获取到的两个邮件唯一id(比如分别是1和2)放入我们搬家数据库。同时也会分别将这两封邮件的内容md5值+邮件大小组成的记录也存入搬家数据库中。这样我们数据库中会有两个从Gmail获取到的唯一id和两个md5+邮件大小的字串。
您再次重试搬家(或系统自动重试),往我们系统存储导入邮件前会计算当前导入邮件内容的md5值+大小,得出一个值。如果这个值在我们搬家数据库中,则认为当前邮件已经搬家成功过,不再导入。在本例中,我们遇到邮件3其实和邮件4是一封邮件,所以它们的内容md5值+大小的值是一样的,当邮件3导入到我们存储成功后,系统会把这个值录入数据库。如果,再此导入邮件4时,邮件4的md5值+大小已经在我们数据库中,则邮件4不再导入,算作导入成功。
注意:如果一封邮件既在收件箱又在垃圾箱中,根据上述重复邮件去重逻辑,实际上这封邮件只会往我们系统导入一次,所以我们系统搬家成功后的邮件数可能会少于您之前使用的邮局(老邮局)中记录的邮件数。