Discuz!积分同步/多站点用户积分提醒消息数据同步

Discuz多论坛用户积分同步 Discuz多论坛积分同步 Discuz多站点用户信息数据同步
文章已有最新版:https://www.fity.cn/post/457/
最后更新:2014-02-10 12:08
     关于Discuz积分同步,近期将重新发布一篇新文章介绍在discuzX3中实现discuz用户积分同步。本文bug不在修复。
最后更新:2013-04-23 22:19
     修复了已知bug。如使用,请确定自己对Discuz或mysql服务器有所了解或联系未来往事获取帮助。另外就是目前Discuz已发布X3测试版产品和Discuz的程序版本的生命周期时间,建议你往高版本升级。


录入时间:2013-04-10 23:55
前段时间有几个discuz上面的网友在QQ上问针对discuzX1.5-X2.0多论坛、站点环境下如何同步各个站点的用户相关数据信息(例如:积分、消息、提醒、勋章获得情况等),确保多站点用户数据的一致性,提升用户体验,于是整理了这篇文章。如果要实现这样的结果,很显然需要共用用户数据信息,当然从程序或是服务器方面综合来说实现方法也有很多种。

本文基于Discuz!X2.0版本程序、独立主机(如果为虚拟主机需要修改部分内容)环境所写,阐述的方法是通过Discuz的分布式部署+MySQL触发器实现这一需求。
Discuz在X1.0版本发布以后开始支持在多个数据库之间操作,到X2.0版本可以看到分布式MySQL部署已经有个趋势但依然并不完善、存在诸多的bug。官方的回复是目前X2.0依然不支持分布式部署。不过现在好多站点都已经升级到X2.5版本,X2.5版本官方给出的产品文档中已指出支持分布式MySQL部署,X3.0中官方曝光支持站点热点数据缓存层和数据库分布式部署,在架构、性能、移动互联网方面逐渐增强。

闲话不多说了,下面进入正题:

环境相关信息约定:
Discuz版本:DiscuzX2.0(未集成UCenter Home)
                   UCenter1.6.0(单独的域名:uc.www.fity.cn)
站点域名:a.www.fity.cn 和 b.www.fity.cn(这里我们需要实现这两个站点的用户积分同步)
MySQL版本:5.0.x
数据库相关信息:
    a.www.fity.cn 使用MySQL数据库:bbs_a
    b.www.fity.cn 使用MySQL数据库:bbs_b
    积分同步的表存储到公共数据库:memberdata(该库存储用户的信息和积分,第二主库<读写>,部分页面依然读配置文件中定义的db1下的用户表)
补充信息:由上面的介绍,我们知道在Discuz未来新版本中已经对分布式部署有了更好的支持,所以这里我们考虑到未来架构的移植及可扩展性把需要同步的数据表单独存储到一个公共的数据库memberdata中,实现过程简单示意图:
点击在新窗口中浏览此图片


一、暂时对站点进行关闭操作,以确保各数据库暂时不再被写入
  后台——关闭站点

二、额外了解一些基础:Discuz主要性能优化瓶颈表
  • member表
  • Post表
  • Thread表点击数
  • DIY模块数据更新
  • 帖子点评和评分功能的

Discuz!X系统功能丰富,数据表多达200多个,在实际生产环境中对各种功能的深度使用各不一样,导致每个数据表都有可能承受高并发的访问压力,当出现这种情况时,需要将负载大的数据表及其相关数据表单独部署,以增强系统的负载能力。
这里我们先来看下Discuz!X2.5的分布式部署。Discuz!X2.5理论上支持以表为单位的数据库分布式部署,部分无法独立部署的表将与其相关表被合并为最小部署单位。以下图为例:
点击在新窗口中浏览此图片

三、在Discuz!X2.0中配置MySQL数据库分布式部署,这里我们把pre_common_member和pre_common_member_count两张表部署到第二台数据库服务器(公共用户信息数据库),编辑a.www.fity.cn和b.www.fity.cn站点的config_global.php配置文件,CONFIG DB配置区域参考如下内容:
代码中暴露了php脚本代码,未能正常显示,请联系未来往事更正文章……


至此,Discuz!X2.0中的MySQL数据库分布式部署几乎完成了。
需要注意:这里我们需要确保`memberdata`库下的表的信息数据是最终数据(最完整的数据),同时同步给a.www.fity.cn和b.www.fity.cn各一份(这里可能在同步一份到各个站点,这样公共库memberdata下的pre_common_member和pre_common_member_count两张表的数据和各个论坛库库下的pre_common_member和pre_common_member_count两张表不是重复了吗?分布式还有什么意义?当你部署完成后就知道原因:同为主库,Discuz!X2.0下设计理念是第二服务器上`memberdata`库pre_common_member和pre_common_member_count两张表可读写,但部分页面读取依然会读第一服务器上的数据,这里不再过多赘述。如果可以建议更新到新版本discuz程序或自行修改程序代码进行调整,这里本文重点介绍的是通过MySQL触发器实现各表数据同步。)如果你的站点数据表之间在这里没有同步,后面完成后你可能会遇到如下错误信息:
点击在新窗口中浏览此图片

更多配置信息请至官方阅读“Discuz!X2.5新版架构优化说明——X2.5的新程序架构”:
http://dev.discuz.org/wiki/index.php

四、利用MySQL触发器将`memberdata`库下pre_common_member和pre_common_member_count两张表的数据同步给a.www.fity.cn和b.www.fity.cn站点
分别在`memberdata`库下pre_common_member和pre_common_member_count两张表创建insert、update、delete触发事件,这里以创建pre_common_member表的触发器为例:
1、建立与bbs_a用户数据同步的触发器

#insert触发器
drop trigger pre_common_member_insert;   //如果该触发器存在则删除
delimiter |
create trigger pre_common_member_insert
after insert
on `memberdata`.`pre_common_member`  //触发器执行的表
for each row
begin
insert into `bbs_a`.`pre_common_member`      //被触发的表
(`uid`,`email`,`username`,`password`,`status`,`emailstatus`,`avatarstatus`,`videophotostatus`,`adminid`,`groupid`,`groupexpiry`,`extgroupids`,`regdate`,`credits`,`notifysound`,`timeoffset`,`newpm`,`newprompt`,`accessmasks`,`allowadmincp`,`onlyacceptfriendpm`,`conisbind`) VALUES (new.uid,new.email,new.username,new.password,new.status,new.emailstatus,new.avatarstatus,new.videophotostatus,new.adminid,new.groupid,new.groupexpiry,new.extgroupids,new.regdate,new.credits,new.notifysound,new.timeoffset,new.newpm,new.newprompt,new.accessmasks,new.allowadmincp,new.onlyacceptfriendpm,new.conisbind);
end |
delimiter ;

#update触发器
drop trigger pre_common_member_update;   //如果该触发器存在则删除
delimiter |
create trigger pre_common_member_update
after update
on `memberdata`.`pre_common_member`  //触发器执行的表
for each row
begin
update `bbs_a`.`pre_common_member` set uid=new.uid,email=new.email,username=new.username,password=new.password,status=new.status,emailstatus=new.emailstatus,avatarstatus=new.avatarstatus,videophotostatus=new.videophotostatus,adminid=new.adminid,groupid=new.groupid,groupexpiry=new.groupexpiry,extgroupids=new.extgroupids,regdate=new.regdate,credits=new.credits,notifysound=new.notifysound,timeoffset=new.timeoffset,newpm=new.newpm,newprompt=new.newprompt,accessmasks=new.accessmasks,allowadmincp=new.allowadmincp,onlyacceptfriendpm=new.onlyacceptfriendpm,conisbind=new.conisbind where uid = new.uid;
end |
delimiter ;

#delete触发器
drop trigger pre_common_member_delete;
delimiter |
create trigger pre_common_member_delete
after delete on `memberdata`.`pre_common_member`
for each row
begin
delete from `bbs_a`.`pre_common_member` where id=OLD.uid;
end;
|
delimiter ;


2、建立与bbs_b用户数据同步的触发器
修改上面的部分SQL语句即可实现。

对于pre_common_member_count表的触发器创建这里不再过多赘述。如果需要请参阅:
《MySQL触发器 触发程序 详解及实例》https://www.fity.cn/post/352/
MySQL触发器 触发程序语句代码在线生成 https://www.fity.cn/other/mysqltrigger.php

至此配置结束,如有疑问请评论讨论。

相关文章

此处评论已关闭