Redis 4のUNLINKでサーバー負荷を抑えてみる(Redis Cluster)

Redis4.0のUNLINKを使ってみる

こんにちは、サーバーサイドエンジニアの菅原です。
今回は今更ながらRedis4系から追加されたUNLINKコマンドについて調べて検証してみました。

背景

Webアプリケーションのパフォーマンスを向上しようとするときRedisは強力なツールです。
ですがRedisを運用する注意点としてRedisの容量の懸念が見込まれます。
キーがどんどん積み上がるとRedisの容量を大きく圧迫し、そうなるとRedisはキーの検索に時間を要するのとキーを削除するときもサーバーに負荷がかかりサーバーダウンしてしまうことも考えられます。

setした時に設定したexpireが切れたキーも完全に消えることは確証されなく、
ゴミのデータが残る場合があるのでDELコマンドで定期的に掃除が必要になります。
しかしRedis3までのDELコマンドは一度に指定されたキーを全てアクセスして削除しようとするのでその間はRedisは他の処理を受け付けないため
Redisに膨大なサーバー負荷がかかり、Redisが落ちてしまったり、クラスターダウンの影響にも繋がります。
今回はその問題を解決するためにRedis4系で新たに追加されたUNLINKコマンドについて紹介します。

Redis4とは

Redis4は2017年7月14日にリリースされました。現在は4.0.10までのバージョンが出ています。
4系で追加された仕様の中でもっとも気になったのはモジュール機能とUNLINKコマンドの追加です。

モジュール機能はRedisの型やコマンドなどを拡張できる機能で
UNLINKコマンドは非同期にキーのデータを削除してくれることで
スレッドの待ち時間なしにデータを順に削除することができる機能です。
今回は実際にUNLINKコマンドを扱って挙動を確認してみましょう。

今回の目標とゴール

  1. Redis Clusterを構築する
  2. Redis Clusterにデータをセットする
  3. UNLINKコマンドで容量が大きいキーTOP10を削除するシェル作成
  4. 実際に登録したデータが反映されているか確認する

環境

  • Mac OS
  • redis-4.0.9

Redis Clusterを構築する

まずは公式HPから自分のマシンにRedis 4をダウンロードして解凍します。

https://redis.io/download

以前に環境構築した記事で細かい設定などを執筆してあるのでそちらも参考にしてください。

初めてRedisを使うための環境構築

上記インストールが完了したら
redis-serverを立ち上げましょう(brew)など/usr配下のredisを起動したい場合はそのパスに合わせてredis-serverコマンドを入力します。

redisが立ち上がったらredisのコマンドラインを立ち上げます

無事立ち上げることができたら成功です。デフォルトでは6379のポート番号でredisが立ち上がっていることがわかります。

そして早速Redis Clusterを構築するためのCluster構成を設計しましょう
今回はClusterを構成するための最低限のCluster構成(master: 3台, slave: 3台)で設計して構築します。
図で表すとこんな感じです。

Caching Cluster Architecture (2)

Port(7000~7005)までのRedisでクラスターを構築していきます。
まずは先ほど立ち上げたredisサーバーを閉じてcluster-testディレクトリを作成します。
作成が完了したらその中に(7000~7005)までのディレクトリの部屋を用意してあげます。
用意ができたらそれぞれの部屋にRedisの設定ファイル(redis.conf)を用意してあげます。ポート番号は各自変更してください。
シェルで配布もできそうなのでそこらへんもまた作っていけたらと思います。

各ディレクトリに配布が完了したら各Redisを立ち上げていきましょう。

無事立ち上がったら次にクラスターで各nodeをclusterとして連携させていきます。
今回は redis-trib.rbというrubyで作られたクラスター管理ツールで構築していきます。
(あらかじめgemなどでインストールしておきます)

clusterは3系以降しか構築できないためgemでインストールするredisは3系以上のインストールをお願いします。

redis-trib.rbのバイナリが入ることがわかるので実行していきましょう。
redis-tribはクラスターを構築したり、nodeを追加したり、クラスターやノードの状態をチェックすることもできます。
今回は各MASTERノードにSLAVEを1 対 1 で構築してあげたいのでreplicas 1のコマンドをコマンド内に入れて実行していきましょう

実行が完了するとコンバートしたよとクラスターの構成ができたことがわかります。
[OK] All 16384 slots covered

実際にクラスターの状態を確認します。

これでクラスターが構築されたことがわかります。

Redisにデータをセットする

それでは構築したClusterにデータを投入していきましょう

最初に設定したwp-cluster1のキーバリューは7000(master)のredisに格納され、
そのあとのwp-cluster2はポート7004のredis(master)にリダイレクトで格納されて分散されていることがわかります。

次に先ほど自動的に格納されて切り替わったポート7004のコマンドラインから7000に格納したキー(wp-cluster1)の値を取り出してみます。

7000ポートのredisを参照しに行ってることがわかります!これでredis clusterへのデータの投入ができました。

しかし、上記方法でデータの追加をしてUNLINKを扱うにはかなり面倒です。
Redisにはダミーデータを登録するコマンドがあるのでそれを使いましょう。
ダミーデータはDEBUGコマンドから投入することができます。
それでは1000件のダミーデータを投入していきましょう。

*Clusterではこのダミーデータはslaveへの同期が行われないので注意

登録が完了できたら実際に投入されているか確認します。

1000件のデータが投入されていることがわかります。

それでは実際にこのキーの中でサイズが大きいTOP10を出力してUNLINKするためのシェルを書いていきます。

UNLINKコマンドで容量が大きいキーTOP10を削除するシェル作成

unlink_scan_big_keys.shファイルを作成し、以下のシェルを記載します。

コマンド一つ一つの意味は解説しませんが
7000のredisサーバにあるキーバリューをSCANで読み出し、読み出したデータの情報を加工して
result.outファイルに吐き出します。
result.outに記載しているキーのデータサイズを昇順に並び替え、そのトップ10をUNLINKで削除します。

unlink-keys.sh は別シェルで叩いてますが同一シェル上で問題ありません。

実際に完成したらこのシェルを実行してあげましょう

消す対象に上がったキーのバックアップファイルを参照してそのキーが本当に消されているのか確認します。

nilが返ってきたのでデータが削除されていることがわかります。

今回はトップ10のデータをunlinkで削除しました。

実際にDELコマンドで削除するよりも非同期で安全に削除することができるため
バッチのように定期的に取り扱うことも簡単にできそうです。

まとめ

Redis4系のUNLINKが気になったので軽く触ってみました。
大量にデータをUNLINKしてる場合にも別ターミナルからRedisへデータを投入なども可能で
DELではできなかった操作でデータ量と頻度によってはUNLINKがおすすめであることがわかりました!
redis4.0ではさらに可用性で追加された仕様もあるので皆さんも是非使ってみてください。

ELKで始めるElasticStack6入門 (Elasticsearch, Kibana, Logstash)

こんにちは、サーバーサイドエンジニアの菅原です。
今回はElasticStack6について学んでみたのでその知見を共有したいと思い記事にしました。

はじめに

検索エンジンElasticsearchの検証をしている中でELKと呼ばれるElasticStackの製品について学んでみましたのでそのELKの実行までの流れを記載していきます。

環境

  • Mac OS
  • Elasticsearch 6.2.4
  • Kibana 6.2.3
  • Logstash 6.2.3

入門内容

ゴール:ELKの使い方、及び導入からビジュアライズまでの流れを確認する

ELK

  1. Logstashでデータを扱う

  2. LogstashからElasticsearchにデータを加工し投入する

  3. KibanaでElasticsearchで投入したデータを可視化する

1 . Logstashでデータを扱う

Logstashをインストールします。
ドキュメント通りにインストールしても問題ないですが今回はhomebrewでインストールしました。
logstashがローカルの /usr/local/bin/logstash にインストールされたことがわかります。

https://www.elastic.co/jp/downloads/logstash

では Logstashを実際に起動させて動作を確認していきましょう
Logstashを扱うためにはLogstashにどんなデータに対して(input)どのように加工し(filter)どう出力(output)するかを設定するためのconfファイルが必要になるのでファイルを作りましょう。

ファイルはどこでも大丈夫なのですがここでは /usr/local/Cellar/logstash/6.2.4/bin 配下に logstash.conf を配置しました。

上記を配置しますが今はlogstash.confの雛形をおいただけなので特に設定などは記していません。

実際に起動して確認していきましょう

成功すると最終行にこのような出力でコマンドラインが止まることを確認します。

Pipelines running {:count=>1, :pipelines=>["main"]}

こちらの状態で文字列を入力してみます。

Logstash側から上記のレスポンスが返ってくることが確認できます。
Hello! というメッセージが messageのフィールドに存在していることがわかります。

それではlogstash.confでデータを加工してみましょう

データの加工にはfilterを使います。
filterにも様々な加工を施すAPIが用意されております。

https://www.elastic.co/guide/en/logstash/current/filter-plugins.html

この中で grok と呼ばれるapacheなどのログをフィルタリングするときに便利なfilterを使ってみます。

logstash.confのfilter内にgrokフィールドを追加します。

上記の設定で保存したらひとまず上記を実行してみます。

立ち上がったことが確認できたら以下を入力します。

18/July/2018:19:38:00 -0700 183.60.215.50

レスポンスをみるとフィールドが増えていることがわかります。
入力したログをfilterで確認してデータを分割してくれているのです。
HTTPDATEには日付、IPにはipアドレス、DATAにはメッセージデータが入っていることがわかります。
このようにしてElasticsearchにデータを送る際に事前に加工することによってKibanaで可視化しやすくしたり
Elasticsearchのマッピングに対応した値を投入することができます。
マッピングについては後ほど。。

2. LogstashからElasticsearchにデータを加工し投入する

Logstashでデータを加工して操作することができました。次に加工したデータをElasticsearch側に投入していく準備をします。

Logstashにはデータを扱うためのAPIがデフォルトで様々なファイル形式やサービスに対して扱うことができます。

https://www.elastic.co/guide/en/logstash/current/input-plugins.html

今回はCSV形式のファイルでLogstashからElasticsearch側にデータを送る準備をしましょう

商品情報が入った product.csv というcsvを事前に用意します。
中身は id, title, description, manufacturer, priceのセルの列を持ったデータを用意します。

logstash.confを以下のように編集します

上記の設定ができたらデータを投入していきましょう!

先ほどと同じようにlogstash.confの設定を元にlogstashを起動してあげます。

するとたくさんのデータが投入されていることがわかります。
記事では一部データが投入されているところを記載しております。

投入が終わり次第Elasticsearchでデータができているかの確認をします。

すると約1363件のデータが入っていることが確認できます。

確認できたらKibanaでデータを可視化していきましょう

3. KibanaでElasticsearchで投入したデータを可視化する

それではKibanaでデータを可視化していきましょう(5601ポートでKibanaを起動しています)

先ほど追加したindexの「wp_products」をManagementバーからindex_patternsに追加してあげます。
追加ができたらサイドバーのDiscoverから「wp_products」のインデックスが登録されていることがわかります。

スクリーンショット 2018-06-18 午後0.45.24

登録が確認できたら早速ビジュアライズしていきましょう
サイドバーのVisualizeを押してビジュアライズしたい図・表を選択します。
今回はPieチャートを選択します。

選択したらPieチャートが表示されていることがわかります。
このPieチャートに条件をつけていきます。

  • Priceの範囲(range)で分けてみよう

Bucketsのsplit sliceからRangeでグルーピングして対象フィールドを「Price」にし範囲を設定します。
するとこのようにPieに色がつくことがわかります。

スクリーンショット 2018-06-18 午前1.09.52

  • Priceに対してどのような商品があるのかTermsでIDを使って可視化してみます
    先ほどのrangeに追加で商品ID(Terms)を追加してorderで件数を指定して実行してみましょう

スクリーンショット 2018-06-18 午前2.01.30

どのような商品が入っているかビジュアライズできたことがわかります。
このように様々な条件で図・表をビジュアライズ化し、ダッシュボードを作成することもできます。
x-packのKibana Canvasを用いるとリアルタイムでダッシュボードが更新されていくためこちらも今後は触ってみたいです。

以上でELKの流れを知ることができました。

補足(マッピングについて)

LogstashからElasticsearch側にデータを投入する際にElasticsearch側では何もせずにデータを投入しました。
しかし、実際の業務に使うにはすごく危険です。
というのも wp_productsのマッピングと呼ばれる(RDBMSでいうテーブル設計)を事前に定義しておかないと期待した挙動をしてくれないことがあるからです。

今回のデータでいうとpriceが当てはまります。
今回priceにはドルの単位の小数点を含んだ数字が入ります。

実際にマッピングを定義しないで投入したマッピングをみてみます。

するとpriceフィールドの型がtextになっていることがわかります。
これでは検索クエリでpriceのrangeを絞った場合に意図しない挙動を招きかねません。

そういう事態にならないためにも事前にテーブル定義のようにマッピングを作る必要があります。
小数点がつくマッピングにはpriceに対してfloatの型を指定してあげる必要があります。
今回はmappingに対して新しく追加された型 scaled_float を指定しています。
これはfloatで入ったデータに対してscaling_factorに記述している100を掛け合わせることで
整数値integerに変更するようにしています。これによってコンピュータがfloatにかかる検索処理時間を短縮し
かつdisk容量も減らせることができるので検索時にもパフォーマンスがよくなるからです。

まとめ

いかがでしたか?今回はElasticStack6のELKの基本操作の入門をしました。
プログラミング的要素は多くなく、とっかかりやすく理解もしやすい印象でした。
ElasticStack製品は設定がかなり細かくでき仕様が深くバージョンアップの頻度も高いため
どんなデータに対しても対応策がかなりあり良い反面、知っていないと使えないツールなのでドキュメントを通じて今後も学んでアウトプットしていきたいです。

この度は、ご清覧頂きありがとうございました。
Wedding Parkでは一緒に技術のウエディングパークを創っていくエンジニアを募集しています。
興味のある方はぜひ一度気軽にオフィスに遊びにいらして頂ければと思います。

ブライダル業界のデジタルシフトを加速させるリードエンジニア候補募集!

MySQL 5.7 の透過的暗号化をやってみたよ

こんにちは。SREチーム  インフラエンジニアの綿引です。

今回は MySQL の透過的暗号化 について記載したいと思います。
因みに透過的暗号化が使用できるのは MySQL 5.7.11 からですのでご認識のほど。

前回 は RDS の暗号化について軽く触れましたが、
その際はWebコンソールからボックスにチェックを入れるだけでした。

今回の MySQL の透過的暗号化を使用する場合には設定が必要です。
では早速やっていきたいと思います。

環境

・OS : CentOS 7.1
・データベース : MySQL 5.7.22

続きを読む

33時間クッキング【Kubernetesのラズベリーパイ包み〜ウエパ風〜】

こんにちは、SREチームの西脇(@yasuhiro1711)です。今回は特別番組ということで、33時間クッキング、【Kubernetesのラズベリーパイ包み ウエパ風】をお送りしたいと思います。見逃しそうな方はぜひ録画予約をお願いします。

サイバーの美味しそうなパイ包みを見て、ウエパでも物理的にパイ包みを作ってみることにしました。ローカルマシンやクラウドでもクラスターを組んで利用することは可能ですが、このクッキングを通じてKubernetesのそもそもの理解を深めることを目的としてやりました。

※ なおこちらの記事は、至る所をサイバーエージェントを非常〜〜にオマージュしおります。この記事を了承頂きまして、本当にありがとうございます! オマージュ記事は最後にリンクがございます。

一家に一台、Kubernetesの時代に

この10年でスマホが爆発的に普及したように、Kubernetesが一家に一台の時代がやってきます。本日作るラズベリーパイ包みはそんな時代にもってこい。家庭でお子様からおじいちゃんまで幅広く愛されるであろう、手のひらサイズのKubernetesです。

完成品

完成品はこちらとなります。ジャーン!
Image from iOS (9) 2

続きを読む

Nginxで403 Forbiddenが表示された時のチェックポイント5選

SREチーム  エンジニアの阿久津です。
今回はNginxの403 Forbiddenが表示された時のチェックポイントについて記事にしたいと思います。

環境

  • Vagrant 1.9.5
  • CentOS Linux release 7.1.1503 (Core)
  • Nginx 1.14.0

前提

  • 設定ファイル
     /etc/nginx/default.conf

  • DocumentRoot
     /var/hoge

  • テストページ
     /var/hoge/index.html

続きを読む

【入門】circleci/go-ecs-ecrを使って、CircleCI からAWS ECS にデプロイしてみる

こんにちは、SREチーム、エンジニアの西脇(@yasuhiro1711)です。今日は、circleci/go-ecs-ecrを使って、CircleCI からECS にデプロイをしてみたいと思います。(参考リンクには非常にお世話になりました。ありがとうございます。)

今回は題材にちょうど合う、CircleCIを通じて、AWS ECS/ECR にデプロイするGoアプリケーションがあったのでこれを利用していきます。勉強の題材にとてもよかったです。(しかし注意として、今回利用の「circleci/go-ecs-ecr」は、2018年6月現在、すでに更新されていないため、現在のCircleCIとAWS環境に自分で合わせないと動作できない可能性もあります。ご注意ください。)

最終的に目指すのはこのような設計です。(ECSクラスタ部分は図としては詳細には書いておりません。)

設計

今回の構成では、GitHubにユーザからpushがされると、CircleCIがそれを自動検知し、build実行を始めます。すると最新のソースがECRのレジストリに登録されて、ECSにて定義更新等が走り、EC2内のDockerコンテナにデプロイされる仕組みです。

続きを読む

5分でできる!Python3を利用した自動リンクチェッカーの開発

こんにちは。QAチームでマネージャーをしているエンジニアの斉藤(@saik1010)です。

弊社QAチームで品質向上を目的として取り組んでいる、PythonWebスクレイピングを使用した自動リンクチェッカー(HTTPステータスコードのチェック)について、
環境構築〜実際にリンクチェックを実行するところまでご紹介しようと思います。

環境

環境 バージョン
macOS Sierra 10.12.6
Python 3.6.4
pyenv 1.2.1

続きを読む

Ansible で Node.js を 10系 にアップデートするよ

こんにちは。SREチーム インフラエンジニアの綿引です。

2018/4/24 に Node.js 10系がリリースされましたね。
(私の誕生日です。)

そこで今回は Node.js のアップデートを Ansible を用いて実施する
という記事を書きたいと思います。

Node.js のアップデート方法に関しては、
1. 既存の Node.js(過去に yum でインストール)をアンインストール後、
2. Ansible の shell モジュール を用い Node.js を rpm でインストールする
という形にしました。

10 系を使うものの Node.js に関しての性能や新機能などの検証は行わないので
ご容赦のほどをお願い致します。

続きを読む

QAチーム同士で主催!ユニファ × ウエディングパークの合同LT会

こんにちは。QAチームでマネージャーをしているエンジニアの斉藤(@saik1010)です。

今回は、弊社とユニファ株式会社さんのエンジニア・デザイナーチームで開催した合同LT会(ライトニングトーク)の様子をレポートしたいと思います!

合同LT会の目的

他社のエンジニア・デザイナーとの交流や情報収集を目的として、3ヶ月〜半年に1回のスパンで合同LT会を開催しております。事前にお互いの会社に聞いてみたいことを擦り合わせ、テーマ設定をした上で進めていきます。外部のLT会とは違い、2社というクローズドな場ということもあり、少し踏み込んだ話をできるという点も、合同LT会ならではの大きな魅力の1つです!

続きを読む

LinuC(LPIC) Level1を取得した話

初めまして。SREチーム エンジニアの阿久津です。
今回は仕事の一環でLinuC(LPIC) Level1を取得したことについて記事にしたいと思います。
※受験した当時は「LPIC」という名称でしたが、今は「LinuC」という名称に変わったようですね。

1. LinuC(LPIC)について

1-1. LinuC(LPIC)とは

Linux技術を証明するための資格試験の一つ。正式名称は「Linux Professional Certification」で、略して「リナック」と読みます。
2016年12月時点で、全世界で53万人以上(国内だと約29万人)が受験して、18万人以上の認定者が生まれている資格とのことです。
引用 : LPI-JAPAN 「LPICの魅力をデータで見る」

続きを読む