カテゴリー「redis」

久しぶりにMariaDB以外のことを書いてみる。

 

Redis3.2のrdbファイルは、Redis4に持っていっても、なんの障害もなく移行できる。

リリースノートにも書いてあるし、実際に試してみたところ、問題なく移行でき、キー操作も問題ない。

移行先でAOFを無効化しているので、rdbファイルを移行しただけだが、

AOFを有効化している場合は、aofファイルから復元されるので、注意が必要。

https://raw.githubusercontent.com/antirez/redis/4.0/00-RELEASENOTES

※リリースノートの一番下に、移行についての説明が記載されています。

 

で、Redis4についてですが、

AOFが単なる追記型ファイルとしてでなく、一定時点のスナップショット+追記、という形式(MIXED)に生まれ変わりました。

これにより、Redis3ではすごい速さで肥大化し続けるaofファイルが、

Redis4では肥大化速度が抑制され、さらにaofによる復元速度も早くなり、さらにさらにレプリケーションにも好影響があるということで、

Redis4からはAOFを積極的に使っていくべきだな、と感じております。

 

とはいえ、実際に移行を行う際、まるっとrdbファイルを移行しても、

移行先がAOFを有効化していると、aofファイルから復元が試みられる結果、

rdbファイルが読み込まれず、saveした際には、データがなくなってしまうという悲しい結果に終わる。

 

そこで、Redis3.2からRedis4への移行については、レプリケーションが好ましい。

以下のような形でサーバを組む。

--------------------
redis01 (version:3.2.x, aof:disable)
IP:192.168.35.11
--------------------
 |
 | (replication)
 |
--------------------
redis02 (version:4.0.x, aof:enable)
IP:192.168.35.12
--------------------

このように、移行元(redis01)ではAOFが無効化されており、

移行先(redis02)ではAOFを有効化したい場合、

移行先のAOFを有効化した状態で、レプリケーションを始める。

そうすると、移行先のデータディレクトリ(/var/lib/redisなど)に、rdbファイルとaofファイルの両方が作成される。

 

もし、MIX形式を使いたいなら、

aof-use-rdb-preamble yes

というように、「aof-use-rdb-preamble」を「yes」に設定する必要がある。

実際に、aofファイルにスナップショットが書かれるタイミングは、

auto-aof-rewrite-percentage

auto-aof-rewrite-min-size

という2つのパラメータに依存するため、なかなかaofファイルにスナップショットが書き込まれない場合、これらを小さくするとよい。

あくまで、aofにスナップショットが書かれたことを確認するためで、無理に小さくする必要はない。

ちなみに、aofファイルにスナップショットが含まれているかどうかは、lessコマンドで確認できる)

 

最後に、移行先(redis02)のaof関連パラメータを載せておく。

appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes

 

(参考)

Redis Mixed RDB+AOF

https://qiita.com/devneko/items/67662e016e8cd0b7791a

 

以上

投稿日時:2018年09月06日 16:45   カテゴリー:redis   [コメントがあればどうぞ]

クラウド上のインスタンスにおいて、

Redisのpub/subをしている際、

もし、そのRedisインスタンスがいきなり落ちて、いきなり稼働した結果、

subscribe側が正常にTCP切断を出来ない、

つまりsubscribe側から見れば、まるでRedisへの接続が生きているかのような状態に陥り、

自動的な再接続が機能しないという事態に陥った。。。

 

これは、Redisのsubscribeにはタイムアウトがないという点と、

subscribeが受動的なものであるという特性であるが故に、

発生した問題である。

 

クラウドでは、インスタンスの瞬間的なダウン&アップがたまにあるので、

データベースの自動起動を有効にするかを検討する必要がある。

それはmonitなどによる自動再起動も然りである。

まあ、DISKに書き込むタイプの処理を使っておけば、

このような問題に対して、比較的軽微なダメージで済むかもしれない(もしくはノーダメージ)ので、

その点も留意して、利用プロダクトの選定、プログラムの対応を検討する必要があると思ったわけです。

 

以上

投稿日時:2017年08月30日 23:12   カテゴリー:redis   [コメントがあればどうぞ]

JAVAでredisを使う際、以下のライブラリを使用していた。

https://github.com/mp911de/lettuce

 

このライブラリはとても素晴らしいのだが、

Non Blocking IO機能を、マルチスレッド環境で使おうとすると、

どうもコントロールが難しい。

 

というのもの、このライブラリは内部的にnettyを使っており、

Non Blockingを使う際、nettyのHashedWheelTimerってやつが、

シングルスレッドでtickを刻んでいるため、複数接続を作ろうとすると怒られる。(たぶん作れない)

そもそもredisはシングルスレッドなので、複数接続作ることが間違っているのかもしれないが、

常時接続を1本をマルチスレッド環境で使うのもなんとなく心細い。。

エラーハンドリングでの再接続なども実装しようとすると、

せめてcore数くらい接続を用意しておきたい心持である。。

 

結局Non Blockingはやめて、Blockingを選択したことで、

複数接続を扱えるようになったが、正直結構悩むところである。

 

投稿日時:2017年03月14日 23:05   カテゴリー:java, redis   [コメントがあればどうぞ]

remiレポジトリからインストールしたredis3.2でredis-cliを使うと、

コマンドアシスト(ヒント)が効くようだ。

 

たとえば、zrevrageを打ちたいとき、

zとうつと、アシストが出て、タブ押下で補完できる。

 

redisのコマンドって、なかなか覚えられないと思うが、

アシストがあると覚えやすくていいと思う。

 

以上

投稿日時:2016年07月29日 23:11   カテゴリー:redis   [コメントがあればどうぞ]

持続的接続をredisで行う場合、

接続は1つでよいと書いた記憶があったが、

javaでノンブロッキングでも大丈夫か検証してみた。

 

javaのredisクライアントはlettuceを使用し、

1つのコネクションを、

マルチスレッドで共有し、SET、GETを試みたところ、

結果にずれは生じなかった。

 

結論として、

redisはシングルスレッドであるため、

持続的接続の場合は1コネクションでOK。

 

ただし、javaではマルチスレッドの性能を生かすため、

CPU数 x 2〜3 ぐらいがいいのかなとは思う。

ちなみに、上記でやっても問題なしでした。

 

以上

投稿日時:2015年12月29日 15:38   カテゴリー:java, redis   [コメントがあればどうぞ]

redisの冗長化を行うためには、

  • master <-> slave構成
  • master <-> slave構成 + sentinel
  • cluster

がある。

clusterはredis3より正式サポートされた機能である。

 

特徴としては、以下の通り。

 

master <-> slave構成だと、

masterが倒れたときのフェイルオーバが皆無である。

 

master <-> slave構成 + sentinelだと、

masterが倒れたときに、slaveが自動昇格できる。

ただ、slave x 2以上、sentinel x 3以上が望ましい感じがする。

 

cluster構成だと、

分散でデータを保持しているため、

slaveも同時に使い、自動昇格させる必要がある。(slaveがあれば自動昇格する)

master x 3以上、slave x 3以上にする必要がある。

 

と考えると、clusterが一番な気がするが、

clusterの欠点は以下の通り。

  1. selectはない
  2. multi – execができない?
  3. 対応しているクライアントライブラリが少ない
  4. リダイレクトが発生するため、速度が遅くなる?
  5. クラスター再構築が難しめ

などなど。

とくに、クライアントライブラリが少ないのは気がかりである。

python, rubyではあるらしい。

javaでもlettuceが対応している。

javaのコードは以下の通り。

List<RedisURI> list = new ArrayList<>();
list.add(new RedisURI("192.168.1.45", 16381, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16382, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16383, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16384, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16385, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16386, 1, TimeUnit.SECONDS));

RedisClusterClient client = RedisClusterClient.create(new Iterable<RedisURI>() {
  @Override
  public Iterator<RedisURI> iterator() {
    return list.iterator();
  }
});

AsyncExecutions<String> excutions = null;

RedisAdvancedClusterAsyncCommands<String, String> con = client.connect().async();

AsyncNodeSelection<String, String> masters = con.masters();

excutions = masters.commands().set("hoge", "fuga");

excutions.forEach(result -> result.thenAccept(ret -> System.out.println(ret)));
excutions = masters.commands().get("hoge");

excutions.forEach(result -> result.thenAccept(ret -> System.out.println(ret)));
con.close();
client.shutdown();

 

しかし、multi – execができないのは結構痛い。。。

うまいことやればできるのかな。。

ただ、分散してしまうから、無理なきがする。

 

このlettuceっていうライブラリは良さげ。

nettyをベースに使っていて、

ノンブロッキングをサポートしているしね。

 

投稿日時:2015年12月10日 13:06   カテゴリー:java, redis   [コメントがあればどうぞ]

redisのようなシングルスレッドのDBは、

極端な話コネクションは1つでよい。

 

javaやnode.jsでwebsocketを組んだとき、

1人1コネクションみたいにやっていたが、

そんな必要もない。

 

たくさんのコネクションを維持しても、

redisはシングルスレッドなので、

一度に処理できる命令は1つ。

(※multiを使っても一つと考える)

 

javaの場合は、スレッドセーフな領域に

redisコネクションを格納しておけばよく、

node.jsの場合は、global変数的な扱いで(※クラス外の定義変数かな?)、

コネクションを格納しておけばよい。

 

実際1つのコネクションでは、切断した時の影響が大きいので、

たとえば、a-z0-9の36個とかでもよいかなと。

 

また、MySQLのようなマルチスレッドでは、

コネクションの共用は気を付けておいたほうがよい。

なぜなら、トランザクションがあるから。

 

コネクションをアプリケーション内に維持できる場合は、

こんな風に考えて実装すると効果的だと思います。

 

apache+phpでは無理だけど、

python+wsgiとかではできそう。(railsはわからん)

 

以上

投稿日時:2015年03月20日 15:19   カテゴリー:redis   [コメントがあればどうぞ]