• Stars
    star
    224
  • Rank 177,792 (Top 4 %)
  • Language
    Ruby
  • License
    MIT License
  • Created almost 15 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Add support for master/slave database clusters in ActiveRecord to improve performance.

Seamless Database Pool provides a simple way in which to add support for a master/slave database cluster to ActiveRecord to allow massive scalability and automatic failover. The guiding design principle behind this code is to make it absolutely trivial to add to an existing, complex application. That way when you have a big, nasty application which needs to scale the database you won’t have to stop all feature development just to refactor your database connection code. Let’s face it, when the database is having scaling problems, you are in for a world of hurt and the faster you can fix the problem the better.

This code is available as both a Rails plugin and a gem so it will work with any ActiveRecord application.

Database Clusters¶ ↑

In a master/slave cluster you have one master database server which uses replication to feed all changes to one or more slave databases which are set up to only handle reads. Since most applications put most of the load on the server with reads, this setup can scale out an application quite well. You’ll need to work with your database of choice to get replication set up. This plugin has an connection adapter which will handle proxying database requests to the right server.

Simple Integration¶ ↑

You can convert a standard Rails application (i.e. one that follows the scaffold conventions) to use a database cluster with three simple steps:

  1. Set up the database cluster (OK maybe this one isn’t simple)

  2. Update database.yml settings to point to the servers in the cluster

  3. Add this code to ApplicationController:

include SeamlessDatabasePool::ControllerFilter
use_database_pool :all => :persistent, [:create, :update, :destroy] => :master

If needed you can control how the connection pool is utilized by wrapping your code in some simple blocks.

Failover¶ ↑

One of the other main advantages of using any sort of cluster is that one node can fail without bringing down your application. This plugin automatically handles failing over dead database connections in the read pool. That is if it tries to use a read connection and it is found to be inactive, the connector will try to reconnect. If that fails, it will try another connection in the read pool. After thirty seconds it will try to reconnect the dead connection again.

One limitation on failover is when database servers are down when the pool is being initialized during startup. In this case, the connections cannot be initialized and are not added to the pool. If this happens, you will need to restart your processes once the database servers are back online.

Configuration¶ ↑

The pool configuration¶ ↑

The cluster connections are configured in database.yml using the seamless_database_pool adapter. Any properties you configure for the connection will be inherited by all connections in the pool. In this way, you can configure ports, usernames, etc. once instead of for each connection. One exception is that you can set the pool_adapter property which each connection will inherit as the adapter property. Each connection in the pool uses all the same configuration properties as normal for the adapters.

The read pool¶ ↑

The read pool is specified with a read_pool property in the pool connection definition in database.yml. This should be specified as an array of hashes where each hash is the configuration for each read connection you’d like to use (see below for an example). As noted above, the configuration for the entire pool will be merged in with the options for each connection.

Each connection can be assigned an additional option of pool_weight. This value should be number which indicates the relative weight that the connection should be given in the pool. If no value is specified, it will default to one. Setting the value to zero will keep the connection out of the pool.

If possible, you should set the permissions on the database user for the read connections to one that only has select permission. This can be especially useful in development and testing to ensure that the read connection never have writes sent to them.

The master connection¶ ↑

The master connection is specified with a master_connection property in the pool connection definition in database.yml (see below for an example). The master connection will be used for all non-select statements against the database (i.e. insert, update, delete, etc.). It will also be used for all statements inside a transaction or any reload commands.

By default, the master connection will be included in the read pool. If you would like to dedicate this connection only for write operations, you should set the pool weight to zero. Do not duplicate the master connection in the read pool as this will result in the additional overhead of two connections to the database.

Example configuration¶ ↑

development:
  adapter: seamless_database_pool
  database: mydb_development
  username: read_user
  password: abc123
  pool_adapter: mysql2
  prepared_statements: false # required for ActiveRecord 5
  port: 3306
  master:
    host: master-db.example.com
    port: 6000
    username: master_user
    password: 567pass
  read_pool:
    - host: read-db-1.example.com
      pool_weight: 2
    - host: read-db-2.example.com

In this configuration, the master connection will be a mysql connection to master-db.example.com:6000 using the username master_user and the password 567pass.

The read pool will use three mysql connections to master-db, read-db-1, and read-db-2. The master connection will use a different port, username, password for the connection. The read connections will use the same values. Further, the connection read-db-1 will get twice as many read requests as each of the other two connections, so presumably it’s on a more powerful box.

You must use compatible database adapters for both the master and the read connections. For example, you cannot use an Oracle server as your master and PostgreSQL servers as you read slaves.

Using the read pool¶ ↑

By default, the master connection will be used for everything. This is not terribly useful, so you should really specify a method of using the read pool for the actions that need it. Read connections will only be used for select statements against the database.

This is done with static methods on SeamlessDatabasePool.

Controller Filters¶ ↑

To ease integration into a Ruby on Rails application, several controller filters are provided to invoke the above connection methods in a block. These are not implemented as standard controller filters so that the connection methods can be in effect for other filters.

See SeamlessDatabasePool::ControllerFilter for more details.

More Repositories

1

lumberjack

A simple, powerful, and very fast logging utility that can be a drop in replacement for Logger. Provides support for automatically rolling log files, formatting log output, and tagging log entries.
Ruby
306
star
2

sunspot_index_queue

Asynchronous Solr indexing support for the sunspot gem.
Ruby
82
star
3

last_mod_cache

Simple caching for ActiveRecord models based on the record update timestamps.
Ruby
48
star
4

html_to_plain_text

A ruby gem that can convert HTML to formatted plain text.
Ruby
42
star
5

acts_as_revisionable

ActiveRecord extension that provides revision support so that history can be tracked and changes can be reverted. Emphasis for this plugin versus similar ones is including associations, saving on storage, and extensibility of the model.
Ruby
31
star
6

json_record

Add ability to serialize arbitrarily complex schemas into an ActiveRecord field. You get the benefits of a schemaless database but with all the features of ActiveRecord.
Ruby
24
star
7

acts_as_trashable

ActiveRecord extension that serializes destroyed records into a trash table from which they can be restored. This is intended to reduce the risk of users misusing your application's delete function and losing data.
Ruby
17
star
8

capture_migration_sql

Capture SQL generated by ActiveRecord migrations.
Ruby
15
star
9

sidekiq-process_manager

Process manager for sidekiq.
Ruby
13
star
10

sidekiq-transaction_guard

Guard against invoking Sidekiq workers during database transactions from ActiveRecord.
Ruby
11
star
11

secret_keys

Ruby gem for managing encrypted keys in either JSON or YAML files.
Ruby
10
star
12

support_table_cache

Automatic ActiveRecord caching for small support tables
Ruby
10
star
13

config_object

Feature packed configuration library for Ruby projects.
Ruby
8
star
14

lumberjack_syslog_device

A logging device for the lumberjack gem that writes log entries to syslog.
Ruby
6
star
15

simple_throttle

Simple redis backed throttle ruby gem
Ruby
5
star
16

us_geo

Collection of geographic data for the United States for use with ActiveRecord
Ruby
5
star
17

support_table_data

Extension to load and sync data in ActiveRecord for small support tables from YAML files.
Ruby
4
star
18

ultra_settings

UltraSettings is a Ruby gem that provides a flexible and documented approach to managing application configurations from multiple sources, including environment variables, runtime settings, and YAML files, with an optional web UI for easy documentation.
Ruby
4
star
19

sidekiq-encrypted_args

Support for encrypting arguments to Sidekiq jobs to protect sensitive information.
Ruby
4
star
20

lazy_methods

Gem that adds lazy method wrapping to every object. Preceding any method with lazy_ will defer the invocation until the result is actually needed. This pattern is useful when used with caching systems.
Ruby
3
star
21

super_settings

Ruby
3
star
22

http_configuration

Gem that provides the ability to set defaults for proxies and timeouts for Net::HTTP. Simplifies integration of HTTP calls into any environment and provides a unified interface for setting values.
Ruby
3
star
23

sidekiq-fast-enq

More efficient scheduled job queue implementation for sidekiq to increase throughput in large installations.
Ruby
3
star
24

support_table

Ruby
2
star
25

double_restraint

Ruby gem that provides a mechanism for safely dealing with external resources so that latency does not take down your application.
Ruby
2
star
26

attribute_guard

ActiveRecord extension that allows locking attributes to prevent unintended updates.
Ruby
2
star
27

sidekiq-deferred_jobs

Ruby
2
star
28

http_instrumentation

ActiveSupoprt instrumentation for a variety of Ruby HTTP client libraries.
Ruby
2
star
29

safe_request_timeout

Support for request timeouts for Ruby applications.
Ruby
2
star
30

fast_serializer

Serialization library for Ruby objects that emphasizes speed and efficient code.
Ruby
2
star
31

active_record_query_counter

Ruby
2
star
32

after_commit_changes

Provide support for merging all saved changes in ActiveRecord models for after_commit callbacks.
Ruby
2
star
33

production_open_struct

Patch to the Ruby OpenStruct class to make it more suitable for production environments.
Ruby
1
star
34

lumberjack_mongo_device

A logging device for the lumberjack gem that writes log entries to a MongoDB collection.
Ruby
1
star
35

safe_object_as_json

Re-implementation of the ActiveSupport Object#as_json method but with handling for circular dependencies.
Ruby
1
star
36

simple_thread_pool

Simple ruby thread pool for executing tasks in parallel.
Ruby
1
star
37

lumberjack_data_dog_device

Ruby
1
star
38

factory_bot_any_instance

Ruby
1
star
39

lumberjack_redis_device

Ruby
1
star
40

created_id

Mechanism for optimizing ActiveRecord queries against the created_at column on tables.
Ruby
1
star
41

lumberjack_capture_device

Lumberjack device that can be used in test suites to assert log messages were created.
Ruby
1
star
42

restrainer

Ruby code for throttling workloads so as not to overwhelm external services.
Ruby
1
star
43

cassie

The short and sweet Cassandra object mapper from We Heart It.
Ruby
1
star
44

xml_node_stream

Simple XML parser wrapper that provides the benefits of stream parsing with the ease of using document nodes.
Ruby
1
star
45

url_fetcher

Ruby
1
star
46

capistrano-docker_deploy

Shell
1
star
47

async_methods

Gem that adds asynchronous method calls for all methods on every object to aid in throughput on I/O bound processes. This is intended to improve throughput on I/O bound processes like making several HTTP calls in row.
Ruby
1
star
48

soft_validator

ActiveModel/ActiveRecord validator that can wrap other validators to notify of errors so that new validations can be safely added to an existing model.
Ruby
1
star
49

linux_process_memory

Ruby gem to get a breakdown of the memory being used by a Linux process
Ruby
1
star
50

lumberjack_json_device

Log device for the lumberjack gem to output log entries in JSON format.
Ruby
1
star
51

quiet_logger

Ruby gem for quieting logger output
Ruby
1
star