[Rust]Amazon MemoryDB for Redis にプログラムからアクセスする[JavaScript]
Introduction
Amazon MemoryDB for Redis(以下 MemoryDB)とは、
高可用性かつ耐久性に優れたインメモリデータベースです。
Redis互換なのでioredisやredis-rsなど、
通常のredisクライアントを使用して接続できます。
本稿ではRust/JavaScriptからMemoryDBにアクセスする方法についてご紹介します。
Amazon MemoryDB for Redis?
MemoryDBは、最近東京リージョンでも使用できるようになった、
高速なインメモリデータベースです。
いままでredisといえばキャッシュ用途やWebアプリのセッションデータ保存用途などで
よく選択肢にあがってきてましたが、
これは永続的なデータストとして使えます。
MemoryDBについてはここに詳細な記事があるので、参照してください。
Environment
動作環境です。
aws cliは実行可能な前提です。
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 11.3.1
- Rust : 1.58.1
MemoryDBをセットアップ
まずは今回使用するMemoryDBを作成します。
ここでクラスターの作成をして、
Configuration endpointを確認しておきましょう。
その後、動作確認のため同じVPC内にEC2インスタンスを作成して、SSHでログインします。
※ MememoryDBのセキュリティグループ設定でEC2のセキュリティグループのアクセスを許可
動作確認用に、redisをインストールしましょう。
% sudo yum -y install openssl-devel gcc % wget http://download.redis.io/redis-stable.tar.gz % tar xvzf redis-stable.tar.gz % cd redis-stable % make distclean % make redis-cli BUILD_TLS=yes % sudo install -m 755 src/redis-cli /usr/local/bin/
redis-cliでMemoryDBに接続します。
% redis-cli -h <Configuration endpoint> --tls -p <Port番号> -c
setとgetをそれぞれ試してみます。
your-memorydb:6379>; set memorydb-key "hello memory-db" OK your-memorydb:6379>; get memorydb-key "hello memory-db"
問題なく操作できてます。
では次に、ここでsetした値をプログラムから取得してみましょう。
[参考]
Create Example(Node)
では↑のEC2にNodeをインストールしてアクセスしてみます。
※ Nodeのインストールはこのへん参照
% curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash % . ~/.nvm/nvm.sh % nvm install node % node -v v17.5.0
NodeからMemoryDBへのアクセスはioredisを使います。
% mkdir node-memorydb && cd node-memorydb % npm install --save ioredis
JavaScriptのコードを記述。
↑で設定した値をMemoryDBから取得してみます。
//main.js const Redis = require("ioredis"); //TLSなのでrediss://〜 const HOST = "rediss://<Configuration endpoint>:<Port番号>/"; const redis = new Redis(HOST); async function get_value() { var memorydb_value = await redis.get('memorydb-key'); return memorydb_value; } async function main() { const value = await get_value(); console.log(value); process.exit(0); } main();
注意点は、MemoryDBは暗号化されているので接続するにはURLがrediss://〜になるところです。
ローカルにインストールしたRedisは↑で動いたから、
そのままいけるかと思いましたが、エラー。
MOVED 2247 :<Configuration endpoint>:<Port番号>"
コマンドに対応するハッシュスロットが別ノードにある場合のエラーみたいです。
なので、通常のRedisクライアントではなく、
クラスターに対して接続する必要があります。
//main.js const Redis = require("ioredis"); //Redisクラスターに対して接続 const redis = new Redis.Cluster( [{ "host": "<Configuration endpoint>" }], { dnsLookup: (address, callback) => callback(null, address), redisOptions: { tls: true, } }); async function get_value() { var memorydb_value = await redis.get('memorydb-key'); return memorydb_value; } async function main() { const value = await get_value(); console.log(value); process.exit(0); } main();
hostの指定方法が少し違うので注意。(rediss://〜ではない)
% node main.js hello memory-db
動作OKです。
Create Example(Rust)
Rustでも試してみましょう。
このあたりを参考にRustをインストールしたら、
Cargoでプロジェクトを作成します。
% cargo new sample-memorydb && cd sample-memorydb
RustでのMemoryDB接続はredis-rsを使うので、
Cargo.tomlに↓の記述を追加します。
[dependencies] redis = { version = "0.21.5", features = ["tls","cluster"] }
main.rsを下記のようにします。
Rustでも通常のClientを使用すると、動いたり動かなかったりするので注意。
ClusterClientを使います。
//main.rs use redis::cluster::ClusterClient; use redis::Commands; fn get_value(key:&str) -> redis::RedisResult { let nodes = vec!["rediss://<Configuration endpoint>:<Port番号>"]; let client = ClusterClient::open(nodes).unwrap(); let mut con = client.get_connection()?; con.get(key) } fn main() { let key = "memorydb-key"; match get_value(key) { Ok(v) => println!("{:?}", v), Err(err) => println!("Error:{}", err), } }
runで実行してみます。
% cargo run "hello memory-db"
こちらも動作確認OKです。
Summary
今回はMemoryDBに対してJavaScript、Rustからそれぞれアクセスしてみました。
単一のRedisでなく、Redisクラスターに対してアクセスしている点に注意してください。