Persistence

技術メモなど

GraphQLサーバの設計・実装に関する情報源

GraphQLに関するお仕事に少しだけ関わることができて、そのために最新の情報をキャッチアップしました。 以下、2020年末時点で、私が頼りにしている情報源です。

https://book.productionreadygraphql.com/

  • GraphQLサーバの開発(AppSyncなどのサービスを利用する場合も含めて)に関わるなら必携の書です。

https://principledgraphql.com/

  • GraphQLサーバを設計する上での重要な原則が書かれています。The Twelve-Factor AppのGraphQL版のようなものです。

https://www.apollographql.com/guide/

  • より大きな組織でGraphQLを活用するためのナレッジ集です。

https://www.apollographql.com/blog/https://www.apollographql.com/docs/

  • ApolloのナレッジはすべてのGraphQLの課題解決に役立ちます。

仕事では上記の情報源からエッセンシャルな情報をまとめたので、そのうち公開できるかも。

AWS 認定ソリューションアーキテクト – プロフェッショナル(AWS Certified Solutions Architect - Professional)に合格しました

AWS 認定ソリューションアーキテクト – プロフェッショナル(AWS Certified Solutions Architect - Professional)に合格しました。

基本情報

  • 受験回数: 1回(再認定)
  • 受験日: 2020-12-11
  • スコア: 798 / 1000
  • ベンダー: ビアソン

教材

感想

とにかく文章量が多く、文字を読むのが遅いので時間がギリギリでした。 教材では見たことのないパターンの問題も多数ありましたが、学習した知識から間違った選択肢は分かるものもあるので消去法でなんとか選ぶという感じでした。

AWS 認定 データベース – 専門知識(AWS Certified Database - Specialty)に合格しました

AWS 認定 データベース – 専門知識(AWS Certified Database - Specialty)に合格しました。

基本情報

  • 受験回数: 1回
  • 受験日: 2020-11-12
  • スコア: 794 / 1000
  • ベンダー: PSI

教材

感想

約3年ぶりの受験だったのでいろいろ不安がありましたが以下のような感じでした。

  • 時間は画面に表示されるので時計は不要(持ち込み不可)
  • 受験申し込みはローマ字入力ですが、証明書は日本語表記のものでOK
  • 問題数は65問(75問だと勘違いしてペース配分を間違った)

実際の試験はUdemyの問題よりは難しかったです。

Prisma 2.0(Beta)の所感

prisma.io がメジャーバージョンアップして2.0(Beta)になったということなので調査しました。

どう変わったか

www.prisma.io

prismaは様々なリソース(DB, API, GraphQL, など)をインテグレーションしてデータアクセスをprismaに集約するという壮大なコンセプトだったと思ったんですが、2.0はType-SafeなRDBのデータアクセスツールへと着地したようです。

Prisma 2.0の構成要素としては主に、@prisma/cli@prisma/clientを使っていくことになります。この他にマイグレーションツールやGUIもあるようですがそれはまだExprimentalです。

使い方ですが、まずschema.prismaというスキーマ定義ファイルにデータモデルなどの情報を記述していきます。GraphQLのschemaっぽい記述の仕方になっています。そして@prisma/clischema.prismaから型定義を生成します。これが@prisma/clientのパッケージの中に配置されTypeScriptではモデルの型を参照できるようになるという仕組みです。prismaはこの機能をA "smart" node moduleといっています。

prismaは既存のデータアクセスツールととどう違うのか?という点について、以下の記事で説明されています。

Why Prisma? (Comparison with SQL query builders & ORMs)

ORMよりも生産性があり、QueryBuilderよりも(より生のSQLに近い)表現力があるということです。

またその根拠として、ORMやQueryBuilderと比較して以下を挙げています。

  • Thinking in objects instead of mapping relational data
  • Queries not classes to avoid complex model objects
  • Single source of truth for database and application models
  • Healthy constraints that prevent common pitfalls and antipatterns
  • An abstraction that make the right thing easy ("pit of success")
  • Type-safe database queries that can be validated at compile time
  • Less boilerplate so developers can focus on the important parts of their app
  • Auto-completion in code editors instead of needing to look up documentation

この時点ではまだ懐疑的な気持ちだったので、実際にサンプルを触ってみたりドキュメントを一通り読んでみました。

そして今時点の私の感想は以下のとおりです。

所感

TypeORMと比較して型の表現力はprismaの方が高い

  • レスポンスの型が、QueryでSelectしたフィールドやRelationしたテーブルによって都度合成される
  • Queryを組み立てるときの型のサポートがとても強力
  • 生のSQLのレスポンスにも型を適用できる(!)

TypeORMと比較してQueryの表現力はprismaのほうが高い

  • SQLではなくGraphQLっぽい書き方になり、GraphQLに親しんでいると直感的に書ける
  • Queryとして必要な機能はほぼ揃っていて実務レベルで問題ない

トランザクションについて

スキーマ定義ファイルの表現力について

  • 複合フィールドのIndex、Unique制約は書ける
  • String型の値をEnumにできる
  • JSON型はサポートしているけど、その中身については型を与えられなさそう

Modelのビジネスロジックやvalidationについて

データアクセスツールとしては既存のものより良いと思うのですが、Modelがclassでないという点をどう解決するかが実装レベルでネックになりそうと思いました。既存のプロジェクトへの組み込みもしやすいので試行錯誤してみたいと思います。

Redisの基礎知識

Redisについて主に 公式ドキュメント を読み漁った備忘録です。Redisを使って何ができるのかをざっくり知るための情報です。

Redisとは

https://aws.amazon.com/jp/redis/

いきなり公式じゃなくてAWSのドキュメントですが、Redisの特徴やユースケースをわかりやすくまとめられていてとてもイメージが湧いてきました。

チュートリアル

http://try.redis.io/

Try Redisは対話形式でRedisの基本的なコマンドを学ぶことのできるコンテンツです。公式のトップページにもリンクされています。Redisを全く触ったことがない場合は、まずはここでRedisを体験してみるのが良さそうです。

データ型

https://redis.io/topics/data-types-intro

チュートリアルよりも詳しいデータ型についての説明です。

Stream型

https://redis.io/topics/streams-intro

Redis5.0から追加された新しい型です。Pub/Subができる時系列データです。

https://aws.amazon.com/jp/redis/Redis_Streams/

こちらのAWSブログの記事では、Stream型を使った具体例が示されており、理解の役に立ちました。

主要な機能

https://redis.io/documentation

Documentationの Programming with Redis の項目についての概要です。

Pipelining

https://redis.io/topics/pipelining

  • 複数のコマンドをまとめてリクエストする機能です
  • Redis内部ではコマンドがキューで管理され、全てのコマンドが処理されたらレスポンスが返ります
  • コマンドを1件ずつリクエストするよりも、ネットワークのRTTやRedisコンテキストスイッチを減らすことができ、待ち時間を減らすことができます
  • ReadとWriteをまとめて行いたい場合には、Redis2.6で追加されたScriptingを使います

Redis Pub/Sub

https://redis.io/topics/pubsub

  • チャンネルにメッセージを送信したり、チャンネルをSubscribeする機能です
  • 複数のチャンネルをSubscribeすることができます
  • SubscribeやUnsubscribeにはパターンマッチが使えます
  • パターンマッチの場合はメッセージの形式が通常のメッセージの形式とは異なります
  • パターンマッチでSubscribeシテイルチャンネルのメッセージ受信と、通常のSubscribeしているチャンネルのメッセージ受信は重複します

Redis Lua scripting

https://redis.io/commands/eval

  • Redis2.6で追加されたLuaインタープリタの機能です
  • LuaスクリプトをEVALコマンドで送信してRedis上で実行します
  • Redisの組み込み関数 redis.call(), redis.pcall() などが提供されています

Debugging Lua scripts

https://redis.io/topics/ldb

Memory optimization

https://redis.io/topics/memory-optimization

  • このページは機能ではなくメモリ最適化のためのチェックリストです

Expires

https://redis.io/commands/expire

  • キーにタイムアウトを設定することで、自動的にキーが削除される機能です

Redis as an LRU cache

https://redis.io/topics/lru-cache

  • キャッシュとして利用するときに、メモリの上限に合わせて古いキャッシュを削除する機能です
  • LRUというアルゴリズムでキャッシュを管理します
  • Redis4.0ではLFUというアルゴリズムも導入されました

Redis transactions

https://redis.io/topics/transactions

  • コマンドをグループにして実行する機能です
  • グループのコマンドが実行されるとき、他のコマンドの割り込みは発生しないのでアトミックな操作として実行できます
  • つまりグループのコマンドがすべて処理されるか、全て処理されないかのいずれかの状態になります

Mass insertion of data

https://redis.io/topics/mass-insert

  • 大量のデータを挿入する機能です
  • 1コマンドずつ登録する方法や、Pipelineを使って登録する方法は推奨されません
  • データが書かれたファイルを読み込ませて登録する方法を利用します

Partitioning

https://redis.io/topics/partitioning

  • 複数のインスタンスでデータを分割する機能です
  • すべてのインスタンスにはキーのみを格納し、データは分散して管理します
  • 1台のコンピュータのメモリ搭載量を超えるデータを扱うことができるようになります

Distributed locks

https://redis.io/topics/distlock

  • RedlockというアルゴリズムによりRedisで分散ロックを実装する方法を記載しています
  • 実際にそれを行うのはクライアントライブラリです

Redis keyspace notifications

https://redis.io/topics/notifications

  • Redis2.8で追加されました
  • Pub/Subのチャンネルを通してメッセージ以外の情報を通知する機能です

Creating secondary indexes with Redis

https://redis.io/topics/indexes

  • 構造化されたデータに対してインデックスを追加する機能です
  • ソートされたセット型のデータのソートキーにインデックスを作ることでvalueとObjectIDのインデックスを作ったりできます
  • ただしインデックスの値は手動で登録/更新が必要です
  • いろいろ柔軟に使えそうです

Redis modules API

おわり

RedisについてはSidekiqのデータストアとしてしか利用したことがなかったのですが、キャッシュやPub/Subやその他にも色々な使い方ができそうということが分かりました。Pub/SubやStreamについてサンプル実装などがあったので、次は手を動かしてみたいと思います。

参考

HTTP負荷テストツール vegeta をサポートする nappa というツールを作りました

vegeta というGoで作られたHTTP負荷テストツールがあります。

github.com

初めて使ってみたのですが、シナリオや状態(Cookieなど)を伴わない単純な負荷テストにはこれで十分と感じました。

ですが、ターゲット(リクエスト)の指定について、単純なGETリクエストなら良いのですが、ヘッダーやボディを含めると指定がやや面倒と感じました。具体的には、RFC 2616形式のテキストファイルにターゲットの情報(URLやヘッダー、ボディなど)を書いて読み込ませるか、JSON Schema形式で標準入力として渡すかの、2通りの方法があります。いずれも普段扱うフォーマットではないため、これを手作りする必要がありました。

そこで、curlコマンドからJSON Schema形式を出力するツールを作りました。curlコマンドであれば、色々なツールから出力できるようになっていることが多いので、簡単に作ることができます。

github.com

このツールにcurlコマンドを食わせると、必要なパラメータだけがJSON Schema形式に変換されて標準出力に出力されます。それをパイプでつないで vegeta に渡してやればいいわけです。

$ nappa <paste a curl command> | vegeta attack -format=json -duration=1s -rate=1/s | vegeta encode

ffmpegでm4aをmp3に一括変換する

備忘メモ。

お風呂場で使っている音楽プレイヤーがmp3形式にしか対応していないのだが、我が家の音楽ファイルはもう大体がm4a(aac)で保存いているため変換が必要になる。

以下のコマンドを使うと、ディレクトリ内のすべてのm4aファイルからmp3ファイルを生成することができる。

fish shell

for file in *.m4a; ffmpeg -i $file -f mp3 -b:a 192k (basename $file .m4a).mp3; end