Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tsukasaoishi/ebisu_connection

EbisuConnection allows access to replica servers
https://github.com/tsukasaoishi/ebisu_connection

activerecord rails replica ruby

Last synced: 3 months ago
JSON representation

EbisuConnection allows access to replica servers

Awesome Lists containing this project

README

        

# EbisuConnection
[![Gem Version](https://badge.fury.io/rb/ebisu_connection.svg)](http://badge.fury.io/rb/ebisu_connection) [![Build Status](https://travis-ci.org/tsukasaoishi/ebisu_connection.svg?branch=master)](https://travis-ci.org/tsukasaoishi/ebisu_connection) [![Code Climate](https://codeclimate.com/github/tsukasaoishi/ebisu_connection/badges/gpa.svg)](https://codeclimate.com/github/tsukasaoishi/ebisu_connection)

EbisuConnection allows access to replica servers.
You could assign a performance weight to each replica server.

```
Rails ------------ Master DB
|
|
+---- Replica1 DB (weight 10)
|
|
+---- Replica2 DB (weight 20)
```

If you could put a load balancer in front of replica servers, should use [FreshConnection](https://github.com/tsukasaoishi/fresh_connection).

## Usage
### Access to Replica
Read query goes to the replica server.

```ruby
Article.where(:id => 1)
```

### Access to Master
If read query want to access to the master server, use `read_master`.
In before version 0.3.1, can use `readonly(false)`.

```ruby
Article.where(:id => 1).read_master
```

In transaction, All queries go to the master server.

```ruby
Article.transaction do
Article.where(:id => 1)
end
```

Create, Update and Delete queries go to the master server.

```ruby
article = Article.create(...)
article.title = "FreshConnection"
article.save
article.destory
```

## Support ActiveRecord version
EbisuConnection supports ActiveRecord version 5.0 or later.
If you are using Rails 4.2, you can use EbisuConnection version 2.4.2 or before.

## Support DB
EbisuConnection supports MySQL and PostgreSQL.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'ebisu_connection'
```

And then execute:

```
$ bundle
```

Or install it yourself as:

```
$ gem install ebisu_connection
```

## Config

config/database.yml

```yaml
default: &default
adapter: mysql2
encoding: utf8
pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password:

production:
<<: *default
database: blog_production
username: master_db_user
password: <%= ENV['MASTER_DATABASE_PASSWORD'] %>
host: master_db

replica:
username: replica_db_user
password: <%= ENV['REPLICA_DATABASE_PASSWORD'] %>
```

`replica` is the configuration used for connecting read-only queries to the database replica. All other connections will use the database master settings.

Config of each replica server fill out to `config/replica.yml`

```yaml
production:
- "replica1, 10"
- "replica2, 20"
-
host: "replica3"
weight: 30
```

```yaml
"hostname, weight"
```

String format is it. You can write config with hash.

### use multiple replica servers group
If you may want to user multiple replica group, write multiple replica group to config/database.yml.

```yaml
default: &default
adapter: mysql2
encoding: utf8
pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password:

production:
<<: *default
database: blog_production
username: master_db_user
password: <%= ENV['MASTER_DATABASE_PASSWORD'] %>
host: master_db

replica:
username: replica_db_user
password: <%= ENV['REPLICA_DATABASE_PASSWORD'] %>

admin_replica:
username: admin_replica_db_user
password: <%= ENV['ADMIN_REPLICA_DATABASE_PASSWORD'] %>
```

Config of each replica server fill out to `config/replica.yml`

```yaml
production:
replica:
- "replica1, 10"
- "replica2, 20"
-
host: "replica3"
weight: 30
admin_replica:
- "replica4, 10"
- "replica5, 20"
```

The custom replica stanza can then be applied as an argument to the `establish_fresh_connection` method in the models that should use it. For example:

```ruby
class AdminUser < ActiveRecord::Base
establish_fresh_connection :admin_replica
end
```

The child (sub) classes of the configured model will inherit the same access as the parent class. Example:

```ruby
class Parent < ActiveRecord::Base
establish_fresh_connection :admin_replica
end

class AdminUser < Parent
end

class Benefit < Parent
end
```

The `AdminUser` and `Benefit` models will access the database configured for the `admin_replica` group.

### Master-only Models

It is possible to declare that specific models always use the DB master for all connections, using the `master_db_only!` method:

```ruby
class SomethingModel < ActiveRecord::Base
master_db_only!
end
```

All queries generated by methods on the `CustomerState` model will be directed to the DB master.

### Using EbisuConnection With Unicorn

```ruby
before_fork do |server, worker|
...
ActiveRecord::Base.clear_all_replica_connections!
...
end
```

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

## Test

I'm glad that you would do test!
To run the test suite, you need mysql installed.
How to setup your test environment.

```bash
./bin/setup
```

This command run the spec suite for all rails versions supported.

```base
./bin/test
```