β

RabbitMQ源码之pg模块

Roowe❤ 178 阅读

pg_local

RabbitMQ不想跨节点管理进程组,所以搞了pg_local,功能基本和erlang自带的pg差不多,只是做了小调整。pg的来源是The module is inspired by the ISIS system and the causal order protocol of the ISIS system should also be implemented.

%% 1) Process groups are node-local only.
%%
%% 2) Groups are created/deleted implicitly.
%%
%% 3) 'join' and 'leave' are asynchronous.

数据结构方面是在pg_local_table存了{{ref, Pid}, Ref, N}, {{ref, Ref}, Pid}, {{member, Name, Pid}, N}, {{pid, Pid, Name}},其中有N只会被Insert一次,同一个进程可以被加入多次(同个name或者不同的name),但是只会被erlang:monitor一次,然后得到一个Ref。

总体上,这样的设计是挺巧妙的,某些游戏业务模块可以参考下。

还有一个可以学习的,join的时候是进程pg_local进程去往ETS写入数据,但是读取数据是每个进程自己去读ETS表,这样做到了一个写多个读,性能不会有问题,一个进程被很多进程call的时候,迟早悲剧。当时我们限时限量的商店我也是这样实现的,查还有什么可以买就是每个玩家进程自己去查,但是要买东西就通过全局的购买进程。PS:我当时做的那个项目是单节点多服的架构,如果大世界多个节点,搞限时限量购买就有点意思了,那是待会写的那个pg2的实现。

pg2_fixed

这个模块的修改,其实应该就两行。

join_group: 
     ets:update_counter(pg2_table, Member_Name_Pid, {2, +1, 1, 1})  
leave_group: 
     ets:update_counter(pg2_table, Member_Name_Pid, {2, -1, 0, 0})

bug讨论在http://permalink.gmane.org/gmane.comp.lang.erlang.bugs/1838http://erlang.2086793.n4.nabble.com/pg2-still-busted-in-R13B04-td2230601.html ,没细看bug出现的原因,bug的现象就是数据出现多份,不过最新版的已经修了,而且rabbit mq那份copy也修了,但是代码还是那样,所以懒得纠结这种dirty code了。

--- /usr/local/otp/releases/otp_beam_linux_sles10_x64_r13b_latest/lib/kernel-2.13.5.1/src/pg2.erl   2010-03-09 12:45:05.000000000 +0100 
+++ /clearcase/otp/erts/lib/kernel/src/pg2.erl  2010-05-27 12:53:02.000000000 +0200 
@@ -251,7 +251,9 @@ 
 %%%    Pid is a member of group Name. 
 store(List) -> 
-    _ = [assure_group(Name) andalso [join_group(Name, P) || P <- Members] || 
+    _ = [(assure_group(Name) 
+          andalso 
+          [join_group(Name, P) || P <- Members -- group_members(Name)]) || 
             [Name, Members] <- List], 
     ok.

数据结构方面,总体和pg_local是一样的,只是这个是多节点同步操作,第一次看到这种节点之间加锁和同步操作,觉得挺不错的。如果没有做过节点之间通信开发的同学可以参考pg2的实现,代码也不长,就300+而已。

如果做大世界限时限量的商城没有用mnesia实现的话,就只能像pg2那样操作节点数据之间的唯一性了,蛋蛋好疼。

作者:Roowe❤
33.3% Linux 33.3% Mathematics 33.3% Inspiration
原文地址:RabbitMQ源码之pg模块, 感谢原作者分享。

发表评论