How can we achieve route requests to postgres master using HAproxy

梦想与她 提交于 2020-01-15 10:25:23

问题


I am trying to setup a load balancing for postgres database. We have a postgres master and slave. I configured HA proxy to achieve load balancing. Simple load balancing is working fine.

This database is used for bitbucket.

When bitbucket is writing data to database over the loadbalancer it is fine if it is hitting master, but problem encounters when it is hitting slave(which is in read mode) as it cant update the database.

How can i say HAproxy to route requests to postgres master.

Select * from pg_stat_replication to be executed on master and slave and based on the output it has to route the request to the streaming master, is there any way that we achieve it using HAproxy ?

Thanks, Karthik


回答1:


This can be done using a custom health check, which only succeeds if the server is the master. All the other slave servers will be marked down.

 backend pgsql
   mode tcp
   option tcp-check
   tcp-check send-binary 0000002c # length
   tcp-check send-binary 00030000 # version
   tcp-check send-binary 75736572 # 'user'.bytes.map { |c| c.to_s(16) }
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 6170706c69636174696f6e # 'application'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 6461746162617365 # 'database'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 706f737467726573 # 'postgres'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 00 # name/value terminator
   tcp-check expect string R
   tcp-check send-binary 51 # 'Q'
   tcp-check send-binary 00000020 # length
   tcp-check send-binary 73656c6563742070675f69735f696e5f7265636f7665727928293b # 'select pg_is_in_recovery();'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 58 # 'X'
   tcp-check send-binary 00000004 # length
   tcp-check expect string f
   tcp-check expect string Z
   server pg1 1.2.3.4:5432 check
   server pg2 5.6.7.8:5432 check

The ''tcp-check'' lines are sending and receiving binary packets using the Postgres client protocol, which is defined in their documentation.

In addition, you can also have a secondary 'readonly' backend that is only used if the primary fails. Here's the extra frontend/backend config for that.

 frontend pgsql
   mode tcp
   bind *:5432
   acl readonly.pgsql nbsrv(pgsql) eq 0
   use_backend readonly.pgsql if readonly.pgsql
   acl pgsql nbsrv(pgsql) gt 0
   use_backend pgsql if pgsql

 <...primary backend...>

 backend readonly.pgsql
   mode tcp
   option tcp-check
   tcp-check send-binary 0000002c # length
   tcp-check send-binary 00030000 # version
   tcp-check send-binary 75736572 # 'user'.bytes.map { |c| c.to_s(16) }
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 6170706c69636174696f6e # 'application'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 6461746162617365 # 'database'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 706f737467726573 # 'postgres'
   tcp-check send-binary 00 # string terminator
   tcp-check send-binary 00 # name/value terminator
   tcp-check expect string R
   tcp-check send-binary 58 # 'X'
   tcp-check send-binary 00000004 # length
   server pg1 1.2.3.4:5432 check
   server pg2 5.6.7.8:5432 check

It's debatable if marking slaves as 'down' is a good use of HAProxy health checks. The above does work, but there other ways of doing this without HAProxy.



来源:https://stackoverflow.com/questions/41571150/how-can-we-achieve-route-requests-to-postgres-master-using-haproxy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!