Build Status Code Climate

HandlerSocket

Ruby/C -based zero dependency implementation of MySQL's HandlerSocket protocol.

What is HandlerSocket

HandlerSocket is a NoSQL plugin for MySQL. It works as a daemon inside the mysqld process, accepting TCP connections, and executing requests from clients. HandlerSocket does not support SQL queries. Instead, it supports simple CRUD operations on tables.

HandlerSocket can be much faster than mysqld/libmysql in some cases because it has lower CPU, disk, and network overhead:

To lower CPU usage it does not parse SQL. Next, it batch-processes requests where possible, which further reduces CPU usage and lowers disk usage. Lastly, the client/server protocol is very compact compared to mysql/libmysql, which reduces network usage

Installation

Add this line to your application's Gemfile:

# If you want to use Ruby-based implementation
gem 'handlersocket-rb', require: 'handlersocket/pure'

# If you want to use C-based implementation
gem 'handlersocket-rb', require: 'handlersocket/ext'

And then execute:

$ bundle

Or install it yourself as:

$ gem install handlersocket-rb

Usage

First of all, you need to install handlersocket plugin.

If you are using Percona Server or MariaDB, you already have all necessary libraries.

INSTALL PLUGIN handlersocket SONAME 'handlersocket.so';

And add the following code to mysql config file to mysqld section:

handlersocket_address="127.0.0.1"
handlersocket_port="9998"
handlersocket_port_wr="9999"

Reload MySQL server and run show processlist;. You should see a lot of connections from HandlerSocket.

To create a connection to HandlerSocket run:

hs = Handlersocket.new('host', port)

To open an index run:

hs.open_index('0', 'hs_test', 'users', 'PRIMARY', ['id', 'email'])
# where:
# '0' - index name, you should pass it later to query method
# 'hs_test' - database name
# 'users' - table name
# 'PRIMARY' - index name
# ['id', 'name'] - columns that you want to read/write

To read the data run:

hs.find('0', '=', ['12'], ['100]'])
# This query opens index '0' (primary index from the previous example)
# and finds 100 rows with 'indexed value' = '12'
# similar to
# SELECT id, name FROM hs_test.users WHERE id = 12 LIMIT 100

Benchmarks

See rake:benchmark.

Calculating -------------------------------------
             pure HS     2.000  i/100ms
              ext HS     3.149k i/100ms
              mysql2   669.000  i/100ms
-------------------------------------------------
             pure HS     49.979  (± 2.0%) i/s -    250.000
              ext HS    110.369M (±15.7%) i/s -    467.793M
              mysql2      5.218M (±16.3%) i/s -     23.869M

Comparison:
              ext HS: 110369437.2 i/s
              mysql2:  5218120.6 i/s - 21.15x slower
             pure HS:       50.0 i/s - 2208314.91x slower

Where:

  • ext HS is a C-based implementation of HandlerSocket protocol
  • mysql2 is a default mysql2 adapter
  • pure HS is a Ruby-based implementation of HandlerSocket protocal

Development

After checking out the repo, run bin/setup to install dependencies. Fill handlersocket.yml and mysql.yml in a root directory of the project. Run rake test:db:create to create a default database that is used in tests. Then, run rake to (re)compile the code and run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Run rake benchmark to compare the performance of Ruby HS/C HS/Mysql2.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/iliabylich/handlersocket-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.