暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Moodle-PostgreSQL负载平衡与HAProxy和patroni

原创 eternity 2022-07-18
756

Moodle是一个流行的开源在线学习平台。特别是自2019冠状病毒疾病大流行开始以来,Moodle对学校和大学的重要性进一步增加。在德国的一些州,所有的学校在几天的时间里都不得不切换到Moodle和其他平台,比如BigBlueButton。如果数万名学生突然需要访问Moodle,这会导致可扩展性问题。

除了扩展Moodle应用程序本身之外,还需要考虑数据库。Moodle的数据库选项之一是PostgreSQL。在这篇博文中,我们使用PostgreSQL为Moodle提供了负载平衡选项。

通过Patroni实现高可用性
从教育系统的角度来看,在线学习平台可以被视为关键的基础设施,应该高度可用,尤其是数据库。PostgreSQL的一个好解决方案是Patenti,我们过去曾报道过它的Debian集成。

简而言之,Patenti使用分布式共识存储(DCS)从典型的3节点集群中选择领导者,或者在领导者失败的情况下启动故障转移并选择新的领导者,而不进入分裂大脑场景。此外,Patenti提供了一个REST API,用于节点之间的通信以及来自Patenticl程序的通信,例如在线更改所有节点上的Postgres配置或启动切换。

高可用性客户端解决方案

然而,从Moodle的角度来看,还必须确保它连接到leader,否则就不可能进行写事务。传统的高可用性解决方案(如Pacemaker)在这里使用虚拟IP(VIP),在发生故障转移时,这些IP将被旋转到新的主节点。对于Patroni,有一个vip manager项目,它监视DCS中的leader密钥,并在本地设置或删除集群vip。这也被集成到Debian中。

另一种方法是使用基于PostgreSQL的libpq库的客户端故障切换。为此,所有集群成员都列在连接字符串中,并添加了连接选项target_session_attrs=read-write。通过这种方式配置,如果连接断开,客户端将尝试访问其他节点,直到找到新的主节点。

另一种选择是HAProxy,一种高度可扩展的TCP/HTTP负载平衡器。通过对每个节点的Patenti REST API执行定期健康检查,它可以确定当前的领导者并将客户端查询转发给它。

Moodle数据库配置

Moodle与PostgreSQL数据库的连接在配置中配置。php,例如,对于简单的独立数据库:

$CFG->dbtype    = 'pgsql';
$CFG->dblibrary = 'native';
$CFG->dbhost    = '192.168.1.1';
$CFG->dbname    = 'moodle';
$CFG->dbuser    = 'moodle';
$CFG->dbpass    = 'moodle';
$CFG->prefix    = 'mdl_';
$CFG->dboptions = array (
  'dbport' => '',
  'dbsocket' => ''
);

此处使用默认端口5432。

如果使用流复制,备用项还可以定义为只读,并分配给自己的数据库用户(只需要读取权限):

$CFG->dboptions = array (
[...]
  'readonly' => [
    'instance' => [
      [
      'dbhost' => '192.168.1.2',
      'dbport' =>  '',
      'dbuser' => 'moodle_safereads',
      'dbpass' => 'moodle'
      ],
      [
      'dbhost' => '192.168.1.3',
      'dbport' =>  '',
      'dbuser' => 'moodle_safereads',
      'dbpass' => 'moodle'
      ]
    ]
  ]
);

使用libpq进行故障切换/负载平衡

如果高可用的Postgres群集与Patroni一起使用,则可以如上所述切换主群集,以防止在发生故障转移或切换事件时丢失数据或关闭系统。Moodle没有提供在这里设置通用数据库选项的方法,target_session_attrs=read-write 因此无法直接设置因此,我们为此开发了一个补丁,并在Moodle跟踪器中实现了它。这允许在$CFG->dboptions数组中添加额外的选项“dbfailover”=>1,该选项添加了必要的连接选项 target_session_attrs=read-write.。自定义配置。php如下所示:

$CFG->dbtype    = 'pgsql';
$CFG->dblibrary = 'native';
$CFG->dbhost    = '192.168.1.1,192.168.1.2,192.168.1.3';
$CFG->dbname    = 'moodle';
$CFG->dbuser    = 'moodle';
$CFG->dbpass    = 'moodle';
$CFG->prefix    = 'mdl_';
$CFG->dboptions = array (
  'dbfailover' => 1,
  'dbport' => '',
  'dbsocket' => '',
  'readonly' => [
    'instance' => [
      [
      'dbhost' => '192.168.1.1',
      'dbport' =>  '',
      'dbuser' => 'moodle_safereads',
      'dbpass' => 'moodle'
      ],
      [
      'dbhost' => '192.168.1.2',
      'dbport' =>  '',
      'dbuser' => 'moodle_safereads',
      'dbpass' => 'moodle'
      ],
      [
      'dbhost' => '192.168.1.3',
      'dbport' =>  '',
      'dbuser' => 'moodle_safereads',
      'dbpass' => 'moodle'
      ]
    ]
  ]
);

使用HAProxy进行故障切换/负载平衡

如果使用HAProxy,则必须将CFG->dbhost设置为HAProxy主机,例如127.0.0.1,以防HAProxy在Moodle服务器上本地运行。此外,可以为读取查询定义第二个端口(例如65432),该端口在CFG->dboptions中配置为只读,与上面的流复制备用端口相同。配置。php将如下所示:

$CFG->dbtype    = 'pgsql';
$CFG->dblibrary = 'native';
$CFG->dbhost    = '127.0.0.1';
$CFG->dbname    = 'moodle';
$CFG->dbuser    = 'moodle';
$CFG->dbpass    = 'moodle';
$CFG->prefix    = 'mdl_';
$CFG->dboptions = array (
  'dbport' => '',
  'dbsocket' => '',
  'readonly' => [
    'instance' => [
      'dbhost' => '127.0.0.1',
      'dbport' =>  '65432',
      'dbuser' => 'moodle_safereads',
      'dbpass' => 'moodle'
    ]
  ]
);

HAProxy配置文件HAProxy。

cfg可以类似于以下示例:

global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen postgres_write
    bind *:5432
    mode tcp
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 3 on-marked-down shutdown-sessions
    server pg1 192.168.1.1:5432 maxconn 100 check port 8008
    server pg2 192.168.1.2:5432 maxconn 100 check port 8008
    server pg3 192.168.1.3:5432 maxconn 100 check port 8008

HAProxy期望在端口5432上输入写入连接(postgres_write),并将其转发到集群成员的端口5432。主端口由端口8008(默认的用户REST API端口)上的HTTP检查确定;Patroni在此返回状态200作为主要,状态503作为备用。

对于读取查询(postgres\u read),必须确定主查询是否也应提供只读查询。如果是这种情况,可以使用简单的Postgres检查(pgsql检查);然而,这可能会导致PostgreSQL日志中出现关于不正确或不完整登录的条目:

listen postgres_read
    bind *:65432
    mode tcp
    balance leastconn
    option pgsql-check user haproxy
    default-server inter 3s fall 3 rise 3 on-marked-down shutdown-sessions
    server pg1 192.168.1.1:5432 check
    server pg2 192.168.1.2:5432 check
    server pg3 192.168.1.3:5432 check

如果您不想让主服务器参与读扩展,您可以简单地使用与postgres\u write部分相同的HTTP检查,这一次需要HTTP状态503:

listen postgres_read
    bind *:65432
    mode tcp
    balance leastconn
    option httpchk
    http-check expect status 503
    default-server inter 3s fall 3 rise 3 on-marked-down shutdown-sessions
    server pg1 192.168.1.1:5432 check port 8008
    server pg2 192.168.1.2:5432 check port 8008
    server pg3 192.168.1.3:5432 check port 8008

修订版Ansible剧本

我们的Ansible Playbook版本0.3中也实现了HAProxy支持,用于在Debian上自动设置三节点PostgreSQL用户集群。新变量haproxy\u primary\u read\u scale可用于决定haproxy是否也应在只读端口上向主节点或仅向跟随者发出请求。

我们很乐意帮忙!

无论是PostgreSQL、Patroni、HAProxy、Moodle还是任何其他开源软件;凭借在开源领域超过22年的开发和服务经验,credativ GmbH可以为您提供无与伦比的个性化支持。我们将帮助您满足所有开源基础设施的需求——如果需要的话,一年365天,一天24小时!

我们期待着您的来信。

原文标题:Moodle PostgreSQL load balancing with HAProxy and Patroni
原文作者:Michael Banck
原文链接:https://www.credativ.de/en/blog/postgresql/moodle-postgresql-load-balancing-with-haproxy-and-patroni/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论