使用plproxy和pgbouncer完成分布式处理

 

plproxy和pgbouncer都是skype开发的基于postgresql的开源应用;前者主要用于完成分布式计算,后者主要充当数据库连接池;它们的主页在[plproxy]和[pgbouncer

plproxy的特性

 

  • 使用plproxy类似于RPC;假设我们有A,B两台数据库,在A在创建一个plproxy的function,并指定一些参数和返回值,就可以在B上也创建一个同名的pgsql函数,并指定同样的参数和返回值;这样,在A上调用该function,通过适当地声明,就可以实现在B上调用该函数的同样效果,但结果是在A上返回的;
  • plproxy还能合并多个结点服务器上返回的结果集,就像是这些结果是由一个函数产生的一样,方便客户端操作;
  • plproxy可以指定同时在所有结点服务器上执行操作,或者只在指定的几台服务器上操作,或者只在任意一台结点服务器上执行操作;
  • plproxy默认是自动提交的;也就是说,只要目标服务器的函数执行成功了,它就会提交;这样有可能造成各个结点数据库的状态并不一致;因为可能有的结点执行成功了,有的没有执行成功,但plproxy并不会因为一个结点失败就回滚其它结点的操作
  • 一开始,我们只有一台账户数据库;但随着账户增加,单个数据库肯定满足不了需求;当多台数据库服务器并存的情况下,需要解决负载平衡的问题;

    为此,我们在系统的syshostconfig表中存储了一个key为accountNum,value为整数的参数;每次进行开户操作时,先用plproxy在所有数据库上查出该值并返到proxy层;由pgsql函数找出哪个数据库的accountNum最小,然后就在该数据库上开户,并将对应的accountNum加1

    这样,新增服务器将立即开始承担新用户的注册;原有服务器压力不变; 

    plproxy中的死锁

    考虑两个账户a@a.com和b@b.com,如果出现a@a.com向b@b.com转账,恰好b@b.com也在向a@a.com转账,就会出现死锁的情况;即一个进程已经拿到a@a.com的锁,并等待b@b.com,而另一个进程拿到了b@b.com的锁,并等待a@a.com;

    一个可行的解决办法就是所有操作都按照一个可以预见的顺序进行;也就是限制转账操作的交易顺序,通过对交易双方的账号进行排序是一个较为简单的办法;

    针对以上问题,如果我们限制对a@a.com的操作,无论是付款还是收款都优先操作,而b@b.com永远都排在它后面,也就解决了死锁的问题;

    因此,在转账交易中,首要任务是对账户名进行排序;至于先收款还先付款,其实不重要


    原创文章如转载,请注明:转载自五四陈科学院[http://www.54chen.com]

    捐款订阅54chen
    捐赠说明

    Comments