Coder Social home page Coder Social logo

grpgrp / heroku-buildpack-pgbouncer Goto Github PK

View Code? Open in Web Editor NEW

This project forked from agriffis/heroku-buildpack-pgbouncer

0.0 1.0 0.0 6.73 MB

Run pgbouncer and stunnel in a dyno along with your application

License: MIT License

Shell 95.51% Dockerfile 4.49%

heroku-buildpack-pgbouncer's Introduction

Heroku buildpack: pgbouncer

This is a Heroku buildpack that allows one to run pgbouncer and stunnel in a dyno alongside application code. It is meant to be used in conjunction with other buildpacks as part of a multi-buildpack.

The primary use of this buildpack is to allow for transaction pooling of PostgreSQL database connections among multiple workers in a dyno. For example, 10 unicorn workers would be able to share a single database connection, avoiding connection limits and Out Of Memory errors on the Postgres server.

It uses stunnel and pgbouncer.

FAQ

  • Q: Why should I use transaction pooling?

  • A: You have many workers per dyno that hold open idle Postgres connections and and you want to reduce the number of unused connections. This is a slightly more complete answer from stackoverflow

  • Q: Why shouldn't I use transaction pooling?

  • A: If you need to use named prepared statements, advisory locks, listen/notify, or other features that operate on a session level. Please refer to PGBouncer's feature matrix for all transaction pooling caveats.

Disable Prepared Statements

With Rails 4.1, you can disable prepared statements by appending ?prepared_statements=false to the database's URI. Set the PGBOUNCER_PREPARED_STATEMENTS config var to false for the buildpack to do that for you.

Rails versions 4.0.0 - 4.0.3, reportedly can't disable prepared statements at all. Make sure your framework is up to date before troubleshooting prepared statements failures.

Rails 3.2 - 4.0 also requires an initializer to properly cast the prepared_statements configuration string as a boolean. This initializer is adapted from this commit. In file config/initializers/database_connection.rb insert the following:

require "active_record/connection_adapters/postgresql_adapter"

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
  alias initialize_without_config_boolean_coercion initialize
  def initialize(connection, logger, connection_parameters, config)
    if config[:prepared_statements] == 'false'
      config = config.merge(prepared_statements: false)
    end
    initialize_without_config_boolean_coercion(connection, logger, connection_parameters, config)
  end
end

Usage

Example usage:

$ ls -a
.buildpacks  Gemfile  Gemfile.lock  Procfile  config/  config.ru

$ heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

$ cat .buildpacks
https://github.com/gregburek/heroku-buildpack-pgbouncer.git#v0.3.3
https://github.com/heroku/heroku-buildpack-ruby.git

$ cat Procfile
web:    bin/start-pgbouncer-stunnel bundle exec unicorn -p $PORT -c ./config/unicorn.rb -E $RACK_ENV
worker: bundle exec rake worker

$ git push heroku master
...
-----> Fetching custom git buildpack... done
-----> Multipack app detected
=====> Downloading Buildpack: https://github.com/gregburek/heroku-buildpack-pgbouncer.git
=====> Detected Framework: pgbouncer-stunnel
       Using pgbouncer version: 1.5.4
       Using stunnel version: 5.02
       Using stack version: cedar
-----> Fetching and vendoring pgbouncer into slug
-----> Fetching and vendoring stunnel into slug
-----> Moving the configuration generation script into app/bin
-----> Moving the start-pgbouncer-stunnel script into app/bin
-----> pgbouncer/stunnel done
=====> Downloading Buildpack: https://github.com/heroku/heroku-buildpack-ruby.git
=====> Detected Framework: Ruby/Rack
-----> Using Ruby version: ruby-1.9.3
-----> Installing dependencies using Bundler version 1.3.2
...

The buildpack will install and configure pgbouncer and stunnel to connect to DATABASE_URL over a SSL connection. Prepend bin/start-pgbouncer-stunnel to any process in the Procfile to run pgbouncer and stunnel alongside that process.

Multiple Databases

It is possible to connect to multiple databases through pgbouncer by setting PGBOUNCER_URLS to a list of config vars. Example:

$ heroku config:add PGBOUNCER_URLS="DATABASE_URL HEROKU_POSTGRESQL_ROSE_URL"
$ heroku run bash

~ $ env | grep 'HEROKU_POSTGRESQL_ROSE_URL\|DATABASE_URL'
HEROKU_POSTGRESQL_ROSE_URL=postgres://u9dih9htu2t3ll:[email protected]:5482/db6h3bkfuk5430
DATABASE_URL=postgres://uf2782hv7b3uqe:[email protected]:5622/deamhhcj6q0d31

~ $ bin/start-pgbouncer-stunnel env # filtered for brevity
HEROKU_POSTGRESQL_ROSE_URL=postgres://u9dih9htu2t3ll:[email protected]:6000/db2
DATABASE_URL=postgres://uf2782hv7b3uqe:[email protected]:6000/db1

Follower Replica Databases

As of v0.3.2 of this buildpack, it is possible to use pgbouncer to connect to multiple databases that share a database name, such as a leader and follower. To use, add the follower's config var to PGBOUNCER_URLS as detailed in the Multiple Databases section.

If you are using Octopus Replication to send reads to a replica, make sure to include the color url of your leader in the SLAVE_DISABLED_FOLLOWERS blacklist. Otherwise, Octopus will attempt to use your leader as a read-only replica, potentially doubling your connection count.

Tweak settings

Some settings are configurable through app config vars at runtime. Refer to the appropriate documentation for pgbouncer and stunnel configurations to see what settings are right for you.

  • PGBOUNCER_POOL_MODE Default is transaction

  • PGBOUNCER_MAX_CLIENT_CONN Default is 100

  • PGBOUNCER_DEFAULT_POOL_SIZE Default is 1

  • PGBOUNCER_MIN_POOL_SIZE Default is 0

  • PGBOUNCER_RESERVE_POOL_SIZE Default is 1

  • PGBOUNCER_RESERVE_POOL_TIMEOUT Default is 5.0 seconds

  • PGBOUNCER_SERVER_LIFETIME Default is 3600.0 seconds

  • PGBOUNCER_SERVER_IDLE_TIMEOUT Default is 600.0 seconds

  • PGBOUNCER_URLS should contain all config variables that will be overridden to connect to pgbouncer. For example, set this to AMAZON_RDS_URL to send RDS connections through pgbouncer. The default is DATABASE_URL.

  • PGBOUNCER_CONNECTION_RETRY Default is no

  • PGBOUNCER_LOG_CONNECTIONS Default is 1

  • PGBOUNCER_LOG_DISCONNECTIONS Default is 1

  • PGBOUNCER_LOG_POOLER_ERRORS Default is 1

  • PGBOUNCER_STATS_PERIOD Default is 60

  • PGBOUNCER_SERVER_RESET_QUERY Default is empty when pool mode is transaction, and "DISCARD ALL;" when session.

  • ENABLE_STUNNEL_AMAZON_RDS_FIX Default is unset. Set this var if you are connecting to an Amazon RDS instance of postgres. Adds options = NO_TICKET which is documented to make stunnel work correctly after a dyno resumes from sleep. Otherwise, the dyno will lose connectivity to RDS.

For more info, see CONTRIBUTING.md

heroku-buildpack-pgbouncer's People

Contributors

ddollar avatar gregburek avatar edwardotis avatar zeke avatar agriffis avatar jhorman avatar benthompson avatar hone avatar tomlea avatar zunda avatar chadbailey59 avatar benrobster avatar timshadel avatar ryanbrainard avatar michaeldiscala avatar mmcgrana avatar lackac avatar jmccartie avatar zacronos avatar cleishm avatar zbuc avatar

Watchers

Randy P. avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.