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

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

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

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

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

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

 

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

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

発生した問題である。

 

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

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

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

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

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

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

 

以上

投稿日時:2017年08月30日 23:12   カテゴリー:redis  

10.1から10.2で変更になるパラメータを見てみた。

個人的に気になるものは以下の通り。

・max_allowed_packet
4MB -> 16MB

・sql_mode
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION -> STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

・innodb_additional_mem_pool_size
removed

・innodb_autoinc_lock_mode
1 -> 2

・innodb_buffer_pool_dump_at_shutdown
off -> on

・innodb_buffer_pool_dump_pct
100 -> 25

・innodb_buffer_pool_load_at_startup
off -> on

・innodb_buffer_pool_size
Dynamic

・innodb_checksum_algorithm
innodb -> crc32

・innodb_compression_algorithm
none -> zlib

・innodb_file_format
Deprecated

・innodb_file_format_max
Deprecated

・innodb_flush_sync
new

・innodb_large_prefix
Deprecated

 

俯瞰してみると、これまで10.1では必ず設定していたパラメータが、

defaultで採用されているケースが多い。

そして、767byteを超えるインデックスについて扱っていた

large_prefixに関係するパラメータがdeprecatedになり、

defaultで3072byteまでインデックスサイズが拡張されるということか。。

 

もうちょい深読みしてみないと、上記の変更が生む弊害が読めないが、

往々にして、より扱いやすい方向に進んでいる気がする。

なお、上記のパラメータの多くはMySQL5.7でも採用されている。

 

以上

投稿日時:2017年08月30日 22:33   カテゴリー:mariadb, mysql  

mysqlではインデックスは1つしか使えないと言われていたが、

実際はインデックスマージという機能があるため、

2つ同時に使うことは可能である。

 

ただ、インデックスマージはwhere句でのみ作用可能に思われるので、

whereとorder byで違うインデックスを使うのは無理なのではないかと思っている。

MySQL5.7でもMariaDB10.2でも、このあたりの記述が見当たらなかった。。

 

上記の理解であっているのか、非常に気になるところである。

進展があったら、書こうと思う。

 

以上

投稿日時:2017年07月23日 00:03   カテゴリー:mariadb, mysql  

fluentdとelasticsearchを長時間つないでいると、

「Cannot get new connection from pool.」というエラーが出る。

これが出ると、fluentdを再起動しなければならなかった。

そのため、logrotateでfluentdを再起動して、この問題を回避していた。

この現象が出るfluentdのプラグインのバージョンは以下の通りであった。

(たぶん、これより古いバージョンでも出てたのでは)

  • elasticsearch : 1.1.pre
  • elasticsearch-api : 1.1.pre
  • elasticsearch-transport : 1.1.pre
  • fluent-plugin-elasticsearch : 1.9.2

 

上記を以下のバージョンに変更したところ、コネクションエラーは一切起きなくなった。

  • elasticsearch : 5.0.4
  • elasticsearch-api : 5.0.4
  • elasticsearch-transport : 5.0.4
  • fluent-plugin-elasticsearch : 1.9.5

 

念のためresurrect_afterという設定も入れてはいる。

 

一応、これで1か月以上再起動かけなくても、エラーは出なくなった。

ちなみに、elastic search本体のバージョンは5系である。

 

以上

投稿日時:2017年07月22日 23:48   カテゴリー:elasticsearch, server  

GaleraClusterでは、書き込みノードを1つに絞って、

デッドロックを回避したほうがいいとよく言われる。

maxscaleを使えば、書き込みノードを絞ることは簡単であるが、

単に3つのクエリーを実行するだけで、書き込みノードを絞れるので、記載しておく。

なお、Perconaも似たような方法をやっていた。

 


1.SHOW GLOBAL STATUS LIKE 'wsrep_local_state'; の結果が4である

2.SHOW VARIABLES LIKE 'read_only'; の結果がoffである

3.SHOW GLOBAL STATUS LIKE 'wsrep_local_index'; の結果が0である

 

以上、3つを満たした場合、書き込みノードとして判定してOK。

haproxyと組み合わせることも簡単なので、

どこかでhaproxyとの組み合わせについても記載しようと思う。

 

以上

投稿日時:2017年07月22日 23:33   カテゴリー:mariadb, mysql  

jettyサーバで、jmx経由でJMV統計を取る方法。

${jetty.base}/start.iniファイルの末尾に以下を追記する。

#
# Initialize module jmx-remote
#
--module=jmx-remote
## JMX Configuration
## Enable for an open port accessible by remote machines
jetty.jmxremote.rmihost=localhost
jetty.jmxremote.rmiport=1099

 

一応これで、rmiで1099ポートにポートにアクセスすると、

JVMのモニタリングができる。

 

以上

投稿日時:2017年06月24日 23:14   カテゴリー:java  

rabbitmqでクラスターを組む際、

クラスターに参加するノードすべてが名前解決によって、

他ノードに接続する仕様となっている。

hostsファイルやdnsmasqなどの簡易DNSを立てるのが簡単ではあるが、

クラウド環境を使っていると、hostsファイルやresolve.confファイルなどが、

再起動等で書き換えられしまうケースもある。

そこで、独自に名前解決を行う必要があるのだが、

erlangの名前解決手法が意外にハマったので、

クラスターの構築手順と合わせて備忘録を残しておく。

 

[バージョン]

os:centos7.2

rabbitmq:3.6.10(rpmで入れた)

 

[前提]

各ノードの情報は以下の通り。

  • 192.168.15.11(ホスト名はbroker01)
  • 192.168.15.12(ホスト名はbroker02)
  • 192.168.15.13(ホスト名はbroker03)

 

[クラスターの構築手順]

1.インストールしたら、とりあえずbroker01,02,03の全台で起動

# systemctl start rabbitmq

この時点では各ノードが個別に動いている状態である。

 

2.broker01,02,03に/etc/rabbitmq/hostsというファイルを以下内容で配備

192.168.15.11 broker01
192.168.15.12 broker02
192.168.15.13 broker03

 

3.brker01,02,03に/etc/rabbitmq/erl_inetrcというファイルを以下内容で配備

{hosts_file, "/etc/rabbitmq/hosts"}.
{lookup, [file,native]}.

 

4.broker01に/etc/rabbitmq/rabbitmq-env.confというファイルを以下内容で配備

export ERL_INETRC=/etc/rabbitmq/erl_inetrc

RABBITMQ_NODENAME=rabbit@broker01
# ↓の設定は、独自です。なければ、デフォルトが適用されます。
RABBITMQ_LOGS=/var/log/rabbitmq/rabbitmq.log
RABBITMQ_SASL_LOGS=/var/log/rabbitmq/rabbitmq-sasl.log
RABBITMQ_PID_FILE=/var/run/rabbitmq/rabbitmq.pid
RABBITMQ_NODE_IP_ADDRESS=0.0.0.0
RABBITMQ_NODE_PORT=5672
RABBITMQ_DIST_PORT=5675

 

5.broker02に/etc/rabbitmq/rabbitmq-env.confというファイルを以下内容で配備
export ERL_INETRC=/etc/rabbitmq/erl_inetrc

RABBITMQ_NODENAME=rabbit@broker02
# ↓の設定は、独自です。なければ、デフォルトが適用されます。
RABBITMQ_LOGS=/var/log/rabbitmq/rabbitmq.log
RABBITMQ_SASL_LOGS=/var/log/rabbitmq/rabbitmq-sasl.log
RABBITMQ_PID_FILE=/var/run/rabbitmq/rabbitmq.pid
RABBITMQ_NODE_IP_ADDRESS=0.0.0.0
RABBITMQ_NODE_PORT=5672
RABBITMQ_DIST_PORT=5675

6.broker03に/etc/rabbitmq/rabbitmq-env.confというファイルを以下内容で配備
export ERL_INETRC=/etc/rabbitmq/erl_inetrc

RABBITMQ_NODENAME=rabbit@broker03
# ↓の設定は、独自です。なければ、デフォルトが適用されます。
RABBITMQ_LOGS=/var/log/rabbitmq/rabbitmq.log
RABBITMQ_SASL_LOGS=/var/log/rabbitmq/rabbitmq-sasl.log
RABBITMQ_PID_FILE=/var/run/rabbitmq/rabbitmq.pid
RABBITMQ_NODE_IP_ADDRESS=0.0.0.0
RABBITMQ_NODE_PORT=5672
RABBITMQ_DIST_PORT=5675

 

7.broker01,02,03に/etc/rabbitmq/rabbitmq.configというファイルを以下内容で配備

[
  {rabbit,
    [
      {loopback_users, []},
      {tcp_listen_options,
        [
          {backlog, 1024},
          {nodelay, true},
          {exit_on_close, false}
        ]
      },
      {vm_memory_high_watermark, 0.4},
      {disk_free_limit, "2GB"},
      {cluster_partition_handling, pause_minority}
    ]
  },
  {rabbitmq_management,
    [
      {listener, [{port, 5676}]}
    ]
  }
].

上記はあくまで一例で、ノード分断の際の生き残り戦略として、小数をダウンさせるという設定にしてます。

 

8.broker01,02,03の/var/lib/rabbitmq/.erlang.cookieファイルの内容を同じにする。
ここで、同ファイルの所有者はrabbitmq:rabbitmqで、権限は0400とする。

 

上記状態で、全ノードを再起動することで、

クラスター状態が完成する。

 

あと、rabbitmq-server.serviceファイルはちょっと変更して以下のようにしている。

デフォルトだと、nofile,noprocあたりがなかったような気がする。。

[Unit]
Description=RabbitMQ broker
After=syslog.target network.target

[Service]
Type=notify
User=rabbitmq
Group=rabbitmq
WorkingDirectory=/var/lib/rabbitmq
ExecStart=/usr/sbin/rabbitmq-server
ExecStop=/usr/sbin/rabbitmqctl stop
NotifyAccess=all
TimeoutStartSec=3600
LimitNOFILE=65536
LimitNPROC=65536

[Install]
WantedBy=multi-user.target

 

公式のドキュメントにだいたい書いてある通りですが。。

気になるのは、hugepageとか、OSレベルのIOのスケジューリングとかかな。

あとは、負荷テストやるのみ。。

また、負荷テストやったら書こうと思います。

 

以上

投稿日時:2017年06月24日 22:50   カテゴリー:rabbitmq  

信頼性の高いメッセージキューを使って、

遅延処理を行うケースの重要性について最近考えるようになった。

そのため、AMQPとか調べていて、rabbitmqを使ってみようかと考えた。

 

とはいえ、rabbitmqはAMQP0.9をベースとしており、

AMQP1.0をベースにしていないなどの点において、

採用候補としては迷うところである。

ActiveMQとかの方がいいかもね、という考えもある。

AMQPではないが、kafkaなどもよさげではあるが、

簡単に調べて、rabbitmqが良さげな点としては、

  • 貧弱サーバでもある程度動く(と思っている)
  • クラスター機能が単体で存在している

といったところでしょうか。

riakを検証しててなんとなくわかったのですが、

開発言語であるerlangはそれほど大きなメモリを使わず、

マルチコアの利用も上手な印象であったため、

他サーバへの相乗り等、縮小することも考えると、悪くないかなーといった具合で検証を進めるてみることにしたというわけです。

ActiveMQやkafkaだと、貧弱サーバで動かすのは厳しい感じがしてます。。

 

で、簡単ながら、検証してみたことろ、メッセージの信頼性の度合はプログラムに依存するような印象を持ってます。

rabbitmq本体に、キューのタイプなどを定義できるのかなーと思っていたが、

特段相違そのような設定などは見られなったため、

プログラムの書き手が信頼性の確保処理の速度について理解しておく必要があるという点が、

中々やっかいでもある反面、融通も効きやすい感じである。

また、諸々検証したら続きを書いてみようと思う。

 

以上

 

投稿日時:2017年06月11日 23:37   カテゴリー:rabbitmq  

以前の記事で、galeraの書き込み能力を向上させるために、

spiderと併用したらいいのではないかと記載した。

しかし、この二つの組み合わせるには、

xa transactions(二相コミット)をあきらめる必要がある。

 

そもそも、galera自体、xaには非対応であり、

また、xa transactionsはバイナリログに対して、クラッシュセーフではないようだ。

(MySQLのドキュメントには記述があったが、MariaDBには記載を見つけられなかった。。)

 

上記前提を踏まえたうえで、

galeraとspiderの共演を実現するためには、xaをあきらめることは必須だが、

そもそもの話として、実装上複数ノードのwriteを極小化しておく必要が十分にあると考えられる。

 

これまで、プログラム側では、begin,begin,commit,commitみたいな実装を平気でしていたが、

そもそもこれ自体が出来るだけ避ける必要のある実装であることを、

今回のgaleraとspiderの共演を実現するために調査していた過程で気づいた。。。

今更の話だが、commitは失敗しないだろうという気持ちがどこかにあり、commitの失敗をリカバリーすることが頭の中から抜けていたように思えて反省している。

 

とはいえ、とはいえ、spiderを挟むことで、

プログラムのシャーディング負担を軽減し、

さらにgaleraで高可用性を確保する組み合わせは、とても魅力的ではある。

 

どこかで、galeraとspiderを共演するために、必要な設定・注意事項等をまとめようと思う。

検証した結果の結論から先に書くと、spiderは受信したSQLを変化させて、バックに投げるため、

場合によっては、SQLの発行回数の増加や、参照取得行数の増加が発生する。

この変化パターンを正確につかんでおかないと、気づかないうちに高負荷をバックに与えてしまう可能性があるため、十分に注意したい。

どっかでこのあたりもまとめてみようと思う。

 

以上

投稿日時:2017年06月11日 23:07   カテゴリー:mariadb, mysql  

MariaDBで準同期レプリケーションで、

猛烈に書き込み中に、MariaDBを停止させ、

単純にslaveを昇格させただけでは、ロストする。

binlogをmasterから救い出さないといけない。

mhaではbinlogを救い出すという処理があるようだが、

当方が使っていたMariaDB Replication Managerにはそのような機能がない。

 

これに対し、Galleraで同じことをやっても、

ロストしなかった。

 

もうちょっといろいろなパターンでやってみないと分からないが、

Galleraのデータ整合性は、準同期よりも1ランク高い気がしている。

ただ、Galleraは書き込み性能がイマイチなので、

フロントにSpiderを置いて、shardingすれば、

高可用性・高負荷耐性をもったシステムが作れそうな気がしている。

 

また進展あれば、記載したいと思う。

 

以上

投稿日時:2017年05月21日 00:50   カテゴリー:mariadb, mysql