Redisにアクセスする
RedisはNoSQL(注1)の一種で、キーバリューストア(注2)に分類されるデータベースです。SQLでMySQLなどのリレーショナルデータベースにアクセスする場合と比べてRedisはデータの読み書きが非常に高速です。RedisではSQLは使えないものの、文字列、リスト(注3)、セット(注4)、ハッシュ(注5)、ソート済ハッシュ(注6)といったデータ型を扱うことができ、Pub/Subの機能もあります。すべてのデータをメモリ上に置くことによって高速化を実現しているため、総データサイズが大きくなりすぎないように注意する必要があります。memcached(注7)とは異なり、データをディスクに永続化することが可能で、またレプリケーションも手軽にできます。RedisはGitHubやFlickrなどの大規模なWebサイトでも使われています。
MySQLは複雑なSQLによる問い合わせができる点が便利ですが、レコード数が多くなってくると速度面での遅さが目立ち、高速化のための対策が必要となってきます。そのような場合、頻繁にアクセスされる一部のデータをMySQLからRedisに移し替えることでアプリケーションの高速化を図ることができます。
従来のリレーショナルデータベースの構造にこだわらないデータベースの総称。SQLを主言語としないことが特徴。Redisの他にCassandra、Riak、MongoDBなどが挙げられる。
キーと値のペアでデータを保存するデータベース。リレーショナルデータベースとは違ってデータ同士は関係性を持たず、SQLで検索することもできない代わりに、読み書きが非常に高速。
文字列の配列。
文字列の集合。同じ文字列は二度出現せず、配列のような要素の前後関係も存在しない。JavaScriptで例えると、値がすべてtrueとなるオブジェクトに相当する。
JavaScriptのオブジェクトに相当する。フィールドと値の組み合わせ。
文字列の集合でありセットと似ているが、各要素がスコアを持つ。スコアによって全体がソートされ、要素どうしの前後関係が生まれる。スコアは重複してもよいが、文字列は重複不可。
メモリ上ですべてのデータを管理するキーバリューストア。データの永続化機能は持たない。多くのWebサイトで使われている。
node_redisのインストール
Node.jsからRedisにアクセスするにはnode_redis(MITライセンス)というモジュールを使います。node_redisをインストールするにはプロジェクトのディレクトリで次のコマンドを実行します。
$ npm install hiredis redis
node_redisの使い方
主な使い方をリスト14に示します。Redisのコマンドがすべてメソッドとして使用でき、コールバック関数の仕組みもすべてのメソッドで共通となっています。
redis = require 'redis'
# 127.0.0.1の6379番ポートで稼働しているRedisサーバに接続する。
client = redis.createClient 6379, '127.0.0.1'
# Redisサーバに接続できなかった場合
client.on 'error', (err) ->
console.log "Error: #{err}"
# すべてのデータを消去する。
client.flushall (err, result) ->
throw err if err
## 基本操作
# key1にvalue1をセットする。
client.set "key1", "value1", (err, result) ->
throw err if err
# key1の値を取得する。
client.get "key1", (err, value) ->
throw err if err
console.log "key1: #{value}"
# key1を削除する。
client.del "key1", (err, result) ->
throw err if err
## ハッシュの操作
# user1のnameとcountryフィールドをセットする。
client.hmset "user1", "name", "山田太郎", "country", "日本", (err, result) ->
throw err if err
# user1のすべてのフィールドと値を取得する。
client.hgetall "user1", (err, user) ->
throw err if err
console.log "名前: #{user.name}"
console.log "国籍: #{user.country}"
## 数値のインクリメント
# visitorsの値に1を加える。該当するキーがなければ自動的に作成される。
client.incr "visitors", (err, result) ->
throw err if err
# visitorsの値を取得する。
client.get "visitors", (err, count) ->
throw err if err
console.log "訪問者数: #{count}"
## リストの操作
# queueにitem1, item2を追加する。
client.rpush "queue", "item1", "item2", (err, result) ->
throw err if err
# queueの値をすべて取得する。
client.lrange "queue", 0, -1, (err, items) ->
throw err if err
console.log "キュー: #{items.join ', '}"
# queueを5秒後に削除する。
client.expire "queue", 5, (err, result) ->
throw err if err
## セットの操作
# usernamesにtaro, jiro, saburoを追加する。
client.sadd "usernames", "taro", "jiro", "saburo", (err, result) ->
throw err if err
# usernamesのメンバーをすべて取得する。
client.smembers "usernames", (err, usernames) ->
throw err if err
console.log "ユーザ名: #{usernames.join ', '}"
## ソート済セットの操作
# scoresに値を追加する。スコア、キーの順で複数指定できる。
client.zadd "scores", 90, "太郎", 100, "二郎", (err, result) ->
throw err if err
# scoresにさらに値を追加する。
client.zadd "scores", 80, "三郎", (err, result) ->
throw err if err
# scoresの最後尾の値を取得する。
client.zrange "scores", -1, -1, "withscores", (err, result) ->
throw err if err
console.log "1位: #{result[0]}君 #{result[1]}点"
Redisサーバへの接続を切断するにはclient.quit()を呼びます。
また、Pub/Subによる配信と購読を行うにはリスト15のように記述します。
redis = require 'redis'
# 同一のサーバに接続するクライアントを2つ作成
client1 = redis.createClient 6379, '127.0.0.1'
client2 = redis.createClient 6379, '127.0.0.1'
client1.on 'subscribe', (channel, count) ->
# client1の購読開始処理が完了した (2)
# client2からmychannelにメッセージを配信する
client2.publish "mychannel", "Message 1"
client2.publish "mychannel", "Message 2"
client2.publish "mychannel", "Message 3"
msgs = 0 # client1が受信したメッセージ数
client1.on 'message', (channel, message) ->
# client1がメッセージの配信を受けた (3)
console.log "#{channel}: #{message}"
if ++msgs is 3 # 3回メッセージを受信したら
# client1の購読をやめる
client1.unsubscribe()
# Redisへの接続を切る
client1.quit()
client2.quit()
# client1がmychannelの購読を開始する (1)
client1.subscribe "mychannel"
このリストでは(1)、(2)、(3)の順番でコードが実行されます。RedisはPub/Subをレプリケーションによってスケールアウトさせることも可能で、シンプルでありながら非常に応用の幅が広いソフトウェアです。
次回も引き続き、CoffeeScriptでNode.jsアプリケーションを開発する際によく使われる実用的な開発手法を紹介します。
