アルパカDiary Pro

はてなブログProではありません

Lua(Luajit)のSplit実装ベンチマーク比較

Luaはsplit関数がバンドルされていません。 そのためいくつか実装が存在しています。

今回、実装違いにより色々問題が出たため再検討していたのですが、 その際にどの実装がパフォーマンス良いのか気になったので比較してみました。
(今回存在を知ったのですが特にOpenRestyのコア実装がどのくらい出るのか試してみたかった)


バージョンなど

Docker Image openresty/openresty:1.15.8.1-3-alpine-fat で実行

ベンチマークコード

コード/セットアップ/実行方法はこちら。
https://github.com/toritori0318/Dockerfiles/blob/master/openresty-split-bench/

結果

10000000回ループでMac上で検証しました。処理時間が短いほど速いです。

項目 処理時間(sec)
ngx_re_split 23.3
lua_split_a 32.8
lua_split_b 49.9
lua_split_c 14.5
lua_split_d 8.91
lua_split_e 29.5


考察

  • ngx_re_split はきちんとメンテされていそうなので品質的には一番安心?OpenRestyで相当なパフォーマンスを要求されない場合はこれで良さそう。また、パターン指定はPCREが利用できるので高機能。
  • Lua 実装は速いもののあるが、実装毎に使い方や仕様が違うので注意(パターン指定方法とか、empty stringの扱いとか)

ローカル環境でGitLab CI実行時、GitLab Container Registoryの認証が度々 `Denied Access Forbidden`になってしまうのを回避する

GitLab CIをテストしたい時、ローカル環境にgitlab-runnerをインストールしてそのままテストすることが出来ます。
蛇足ですが、以下のような感じでセットアップします。

# install
brew install gitlab-runner

# ローカル実行
gitlab-runner exec docker test_job --env hoge=fuga

便利!! 1


GitLab Container Registoryを利用する

GitLabはリポジトリ毎にContainerRegistoryを持つことができます。
.gitlab-ci.ymlに以下のような記述を追記すると利用可能です。

image: oreore-gitlab.com:4567/charisma

services:
  - oreore-gitlab.com:4567/my-redis

test_job:
  script:
    - echo '4000man'

ただし、ローカルPCから実行すると何故か oreore-gitlab.com の認証時に denied: access forbidden でたま~に怒られることがあります。 複数リポジトリを利用していると失敗確率が増えるため、Max Retryに到達してしまいそもそも起動せずに終わってしまうことがあります。

原因/回避方法

そもそもの原因としては、dockerの認証に osxkeychain を利用していると認証が不安定になってしまうようです。
こちらを回避するには、.docker/config.json内の対象のauthにuser:passを直接記述してあげる必要があります。

# base64を得る
echo -n 'username:password' | base64

$HOME/.docker/config.json

{
    "auths": {
        ...
        "oreore-gitlab.com:4567": {
            "auth": "<base64文字列>"
        },
        ...
    },
    "credsStore": "osxkeychain"
}

これで確実に認証を通すことが出来ます。


まとめ

GitLab CI+GitLab Container Registoryをローカルで実行できるのは超絶便利ですが、こんなハマりどころもあるのでご注意くださいませ。


  1. オンデマンドで毎回起動ではなくdocker-composeのように実行環境だけ利用するテクニックもあったりしますが、それはまた別の機会に…

Nginxのアクセスログに機密情報を残したくない方のためのlua-resty-querymask

最近Facebookがパスワードを平文で保存しているというニュースがありましたね。

jp.techcrunch.com

またシステム的に保持していなくても、意図せずアクセスログに情報が残ってしまうことも考えられます。
その対策として安全にアクセスログのマスク処理を行う lua-resty-querymaskというモジュールをご紹介いたします。


使い方

OpenResty のモジュールとして動作します。 以下、README のSYNOPSIS のママです。

local querymask = require "resty.querymask"
local q = querymask:new({
    mode = "writelist",
    mask_part_string = "*",
    mask_part_length = 3,
    mask_fill_string = "*MASK*",
    mask_hash_seed   = "hogefugapiyo",
    max_field_length = 512,
    fields = {
      origin = {"attr1", "attr2"},
      part   = {"attr3"},
      fill   = {"attr4"},
      hash   = {"attr5"},
    }
})
print(q:mask_query_string())

-- (example)
--   curl 'http://localhost/mask?attr1=hogeeee&attr2=fugaaaa&attr3=piyoooo&attr4=fooooo&attr5=barrrrr'
-- 
--   attr1=hogeeee&attr2=fugaaaa&attr3=piy****&attr4=*MASK*&attr5=eoroiaweuroajejrfalwjreoaijrejwaerwaer'


モード

whitelistモード と blacklistモードがあります。
そのままなのですがホワイトリストモードは「fieldsに指定したパラメータのみを対象とし、マスク処理を行う」モードで、ブラックリストモードは「基本的には全パラメータを出力対象とし、fieldsに指定された項目のみマスク処理を行う」モードです。

ターゲット・マスク処理

以下の4種類があります。

  • origin
  • part
    • 項目の一部のみをマスクします。 mask_part_stringmask_part_length の値に準じ処理を行います。
    • ex) 設定が mask_part_string=%, mask_part_length=5 で、指定パラメータ値が abcdefghijklmn の時
      • 出力値=abcde%%%%%%%%%
  • fill
    • 項目の値が設定した固定値でマスクされます。 mask_fill_string の値に準じ処理を行います
  • hash
    • 項目の値をhashingします。 mask_hash_seed の値に準じ処理を行います。

hashingされた値の表示

メールアドレスをハッシュ化したいことはよくあることでしょう。
たとえばメールアドレスをハッシュ化していて、 hogehoge@gmail.com のメールアドレスを検索したい時のハッシュ値を知りたいときは、以下のようなエンドポイントを用意し

curl 'http://xxxxxxxxx/get_hash?data=hogehoge@gmail.com'

といったリクエストを実行するとお手軽にハッシュ値を得ることが出来ます。
(こちらも同様にREADMEに例が載っています)

location /get_hash {
    # なんらかの制限をしておくと良いですね
    allow xxx.xxx.xxx.xxx;
    deny all;

    content_by_lua_block {
        local data = ngx.req.get_uri_args().data

        local querymask = require "resty.querymask"
        local q = querymask:new({
            mode = "writelist",
            mask_part_string = "*",
            mask_part_length = 3,
            mask_fill_string = "*MASK*",
            mask_hash_seed   = "hogefugapiyo",
            max_field_length = 512,
            fields = {
              origin = {"attr1", "attr2"},
              part   = {"attr3"},
              fill   = {"attr4"},
              hash   = {"attr5"},
            }
        })
        -- get hash
        local data_hash = q:get_hash(data)

        ngx.header.content_type = "text/plain"

        ngx.say(data_hash)
    }
}


設定インタフェースについて

自分でもイマイチだと思っているのですが、モジュールの設定インタフェースどうにかしたい気持ち…
ホワイトリストブラックリストを両方包括しているので仕方なくこうしているのもあるのですが、もっとイイ感じの設定方法があればPRくださいませ!


その他便利なところ

クエリパラメータもbodyもまとめて処理しているので、同じインタフェースで同じ変数に簡単に突っ込めるのが割と便利!


まとめ

昨今、セキュリティ関連の話題が尽きません。お手軽かつハイパフォーマンスにマスク処理を行いたいときには検討してみてください。

ECSサービスで「MemberOf placement constraint unsatisfied」が表示されたときの原因

placement constraintsで条件を指定しているサービスで以下のようなメッセージが表示されたとき…

service xxxxxxxxxxxxx was unable to place a task because no container instance met all of its requirements. The closest matching container-instance zzzzzz-zzzzzzzzz-zzzzzzz-zzzzzzzz encountered error "MemberOf placement constraint unsatisfied.". For more information, see the Troubleshooting section.

もしかしたら、インスタンスのリソースが足りていないのかも?

2018年振り返りと2019年

2018年

総括

いつにも増してあっという間でした。濃い一年でしたね。

本厄

でした😇
仕事では特に厄年っぽいことはありませんでしたが、親戚関連ではいろいろありました…

仕事

総評

2018年は大きめの案件がいくつかあったのでそれに注力してました。
また去年くらいまで会社として「やりたい(やっていくべき)ところ」がなかなか進まなかったんだけど、やっとこさ楔を打てたのではないかと思う。
そのあたりのお手伝いもしていて特に大きな問題なく進められたので良かった。割と本気で2019年の動向は楽しみだったりしています。
また、実は去年に引き続き今年も病欠なしでした 😁
別エントリで病気にならない秘訣的なの書こうかなw

ロール

正式に技術チームのマネージャーに任命されたっぽいです。
ただ、自分的にはまだまだマネージメント出来てないので来年はもう少し頑張らねば。
チームメンバーはみなさん優秀なので技術的には全く心配はしてないのですが「チームとしてうまく動ける/会社にコミットできる/エンジニアとして幸せな環境である」といったところを重視してチームビルディングしていければ良いなーと思っています。

家族

娘が小学生に上がりました。息子も順調に体がでかくなってます…すぐ追い越されそう。
ただ、心配は尽きず。
やっぱり小学生にもなると、幼児期と少し悩みの軸が変わってきましたね。
最近の子供達見ていると、もう少しきちんと将来のことを考えて教育していかないとなぁと思っています。
あと家族というか家の中がわちゃわちゃしちゃってきているので、お金を使ってでも解決しようと模索中…
許容範囲を超えてきてて、子供の教育にもよろしくない :(


あと最近忙しくて奥さんとデートできていないのでデートしたい。


2019年

後厄です😇
仕事は今年ターニングポイントだと思ってるので引き続き手を抜かずにがんばります。一発当てて社員全員給料上げてくぞ! 💰

iTerm2から素のTerminalに戻ったら思いの外快適だった件

先日iTermアップデートしたらタブが全く追加されなくなるという現象に陥りました(※最新版は解消している様子)

タブ使いまくる自分としてはだいぶ困るので、仕方がなくMac標準のTerminalに戻ってみました。
すると割と不便なく普通に使えてしまいました :) 1
そんな自分がTermnalに移って最初に設定・確認したことをメモしてみます。


Terminalでやったこと

テーマ変更

標準のテーマがイケてなさすぎるのでいの一番に変えました。調べた結果 iceberg というテーマが良さそうだったので導入してみました。
Iceberg - dark blue color scheme for Vim / Neovim

導入方法

上記サイトの一番下のリンクからファイルをダウンロードし、Terminalの「環境設定」>「プロファイル」>「ギアアイコン」>「読み込み」でファイルを読み込めば設定がimportされます。

f:id:toritori0318:20181111033440p:plain

イメージ

f:id:toritori0318:20181111035840p:plain

だいぶ良い感じになります! 2


ショートカット

リンクジャンプでブラウザ表示

GitLabではgit pushしたあと自動的にマージリクエストへのURLが表示されます。そしてターミナル上でそのままリンクジャンプしてマージリクエストを確認するのはよく利用しています。
こちらの機能に関してはリンクっぽい文字列上で command+ダブルクリック で実現できました。

ダブルクリックで単語っぽいのを文字列選択

Terminalだとダブルクリック時の文字列選択がデフォルトだと微妙です。
たとえば hoge-fuga-piyo という文字列上で fuga にフォーカスあててダブルクリックすると fuga のみ選択されてしまいます。
こちらに関しては shift+command+ダブルクリック で問題なく hoge-fuga-piyo を文字列選択することができます。3

ドキュメント

実はAppleの公式サポートページに出来ること一覧が掲載されています。こちらを見るといろんな発見があるかも。

support.apple.com


Terminalにしてよかったこと

こちらは副作用ですがiTermよりも動作が軽快な気がします。
特に大きなファイルをvimで編集すると割と動作重い時があったのですが、Terminalでは今の所全く気になりません(気持ちの問題かもw)


まとめ

今までiTermを利用していた筆者がTerminalに戻ったお話でした。
Terminalでもそこそこ戦えそうなのでしばらくこのまま利用してみようと思います 🙂



  1. たんに自分がTerminalのことを知らなかっただけというお話w

  2. すみません、vimはmorokaiです😅

  3. 仕様上は「URL文字列として選択」という機能みたいです

redash-dynamic-query v1.0.4をリリースしました

github.com

pypi.org

今回のリリースで以下の改善が行われています。

1.datasource_idを指定しなくても自動で設定するように

今まではdatasource_idが必須だったのですが、これ自動で取得するMRをいただいたので基本指定しなくても良くなりました。わいわい

2.cliコマンド追加

rdq というコマンドが利用できるようになりました。
これにより、今まではpython前提だったのですが、shellからも気軽に利用できるようになっています。

helpはREADME に記載されているので詳細はそちらをご参照ください。

フォーマットは csv / tsv / json が指定できるので様々な用途でご利用いただけるかと思います。 shellだとjsonフォーマット+jqでゴニョゴニョできそうですね!