SlideShare a Scribd company logo
/ 30
Using ngx_lua in pixiv
Harukasan
a.k.a MICHII Shunsuke
2013-06-24
/ 30
はるかさん
インフラ部所属 2年目
Nginx / Apache / MySQL / MongoDB
Kyototycoon / Solr / Traffic Server / Fluentd
Capistrano / Ruby on Rails / Macbook Air / Vim
2
/ 303
• about pixiv Image Cluster
• ngx_lua
• directives in nginx.conf
• nginx api in lua scripts
• ex. code from pixiv Image Cluster
Agenda
/ 304
pixiv Image Cluster
/ 305

Front
Cache Cluster
Image Store

SSD-RAID0
   
HDD SSD
Thumbnailbig size
Memory
DEVICEpeak: 1k req/sec
10Gbps
x20
x20
/ 306

Front
Cache Cluster
Image Store
PRODUCT
Nginx with tmpfs
Traffic Server
Apache / NginxNginx
/ 307
ngx_lua
github.com/chaoslawful/lua-nginx-module
/ 308
• embeds Lua/LuaJIT into Nginx
• has 100% non-blocking API
• has many libraries provided by OpenResty
• memcached, mysql, redis, etc.
ngx_lua
/ 309
# load from /etc/nginx/scripts/?.lua and default root
lua_package_path "/etc/nginx/scripts/?.lua;;";
server {
listen 80;
# GET /fact?a=4 -> 24 (4! = 4 * 3 * 2 * 1)
location /fact {
content_by_lua "
local val = 1
for i = 2, ngx.var.arg_a do
val *= i;
end
";
}
# same code in file
location /fact_script {
content_by_lua_file "fact.lua";
}
}
/ 3010
Directives in nginx.conf
• *_by_lua, *_by_lua_file
• init_by_lua
• rewrite_by_lua
• access_by_lua
• content_by_lua
設定読み込み
rewrite処理
access処理
bodyの生成処理
/ 3011
init_by_lua <code>
masterが設定をロードするタイミングで実行する
init_by_lua " memcached = require 'resty.memcached' ";
server {
! listen 8888;
! default_type 'text/plain';
! location /init_by {
! ! content_by_lua "
! ! local hello = memcached::get('Hello');
...
! ! ";
! }
}
/ 3012
server {
listen 80;
# GET /sum?a=2&b=3 -> 5
location /sum {
set_by_lua $sum "
return tonumber(ngx.var.arg_a) + tonumber(ngx.var.arg_b)
";
echo $sum;
}
}
set_by_lua $res <code>
実行したコードの返値を$resにセットする
/ 3013
server rewrite
find config
rewrite
post rewrite
pre-access
access
post-access
try files
content
logging
Request
rewrite/access/content_by_lua
サーバーコンテキストのrewrite
該当するlocation configを探す
locationのrewrite処理
ファイルへのアクセス
try_fileの処理
bodyの生成
ログ書き込み
access_by_lua
content_by_lua
rewrite_by_lua
rewriteに関連する処理
アクセス制御
bodyの操作
/ 3014
server {
listen 8888;
location /rewrite_by {
rewrite_by_lua "ngx.var.toggle = true";
if ($toggle) {
rewrite / /index_second.html;
}
}
}
rewrite_by_lua <code>
rewriteの前に指定したコードを実行する
/ 3015
server {
listen 80;
# GET /access_by?status=404 => 404 Not Found
location /access_by {
access_by_lua "ngx.exit(ngx.var.arg_status)";
}
}
access_by_lua <code>
access phaseに指定したコードを実行する
/ 3016
# GET /hello
location /hello {
content_by_lua "
ngx.say('Hello, from lua')
";
}
content_by_lua <code>
responseを生成するコードを実行する
/ 3017
Directives in nginx.conf
• LuaスクリプトでNginxの各動作を制御できる
• HTTPで必要な各フェーズでフックできる
• rewrite
• access control
• content generation
ここまで8分
/ 3018
Nginx API in lua scripts
• generate content
• variables and shared tables
• access memcached / MySQL
/ 3019
location /var {
content_by_lua " ngx.say('Hello, from lua!') ";
}
ngx.say content bodyに文字列を出力する
location /var {
access_by_lua " ngx.exit(418) "; # i'm a teapot
}
ngx.exit 指定したステータスコードを返す
/ 3020
location /var {
set $a "alpha";
rewrite_by_lua "ngx.var.b = ngx.var.a .. 'beta'";
echo $b;
}
ngx.var.*
ngx.ctx.*
location /ctx {
access_by_lua "ngx.ctx.foo = 74";
rewrite_by_lua "ngx.ctx.foo = ngx.ctx.foo + 5";
content_by_lua "ngx.say('foo: ' .. ngx.ctx.foo)";
}
Nginxの変数にアクセスする
リクエスト中に共有されるテーブル
/ 3021
ngx.shared.* shared memoryテーブル
http {
lua_shared_dict foo 10m;
server {
location /shared-set {
content_by_lua "
local foo = ngx.shared.foo
foo:set(ngx.var.arg_key, ngx.var.arg_val)
";
}
location /shared-get {
content_by_lua "
local foo = ngx.shared.foo
ngx.say(foo:get(ngx.var.arg_key))
";
}
}
}
/ 3022
Regular Expressions
• ngx.re.match
• ngx.re.gmatch
• ngx.re.sub
• ngx.re.gsub
/ 3023
local matches, err = ngx.re.match("key=val", "([^=]+)=(.+)")
ngx.re.match
ngx.re.sub
matches[0] => "key=val"
matches[1] => "key"
matches[2] => "val"
local newstr,n,err = ngx.re.sub("Hello,lua","lua", "nginx")
newstr = "Hello,nginx"
/ 3024
• OpenResty
• lua-resty-memcached
github.com/agentzh/lua-resty-memcached
• lua-resty-mysql
github.com/agentzh/lua-resty-mysql
• ngx.socketを使って実装されている
Access to memcached/MySQL
/ 3025
Nginx API in lua scripts
• 簡単な処理を書くには十分な関数が
提供されている
• 正規表現
• ハッシュ(md5, sha1)
• ソケット
• OpenRestyを使うとmemcachedへのアクセス
とかも簡単
/ 3026
Example code from
pixiv Image Cluster
/ 3027
Kyototycoon
Logical Delete
Nginx
200
404
/img01.png 200
/img02.png 200
/img03.png 404
/img04.png 200


GET /img01.png GET /img03.png
404
/ 3028
Logical Delete
local memcached = require "resty.memcached"
local uri = ngx.var.request_uri
local memc = memcached:new()
local val, flags, err = memc:get(request_uri)
if val and val ~= "200" then
exit(tonumber(val))
end
logical_delete.lua
location / {
access_by_lua_file logical_delete.lua;
}
/ 3029
Conclusion
• Nginxだけで簡単な処理を実現できる
• アクセス制御とかインプレッション計測
とかには便利そう
• 高速で省メモリ
• メンテナンスコストを抑えられる
/ 3030
References
HTTPLuaModule - Nginx Wiki
http://wiki.nginx.org/HttpLuaModule
chaoslawful/lua-nginx-module - Github
https://github.com/chaoslawful/lua-nginx-module

More Related Content

What's hot (20)

PDF
CI/CDって何が良いの?〜言うてるオレもわからんわ〜 #DevKan
Kazuhito Miura
 
PPTX
Dockerからcontainerdへの移行
Akihiro Suda
 
PDF
Docker Compose 徹底解説
Masahito Zembutsu
 
PDF
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Akihiro Suda
 
PPTX
C# 8.0 非同期ストリーム
信之 岩永
 
PDF
MySQLとPostgreSQLの基本的なレプリケーション設定比較
Shinya Sugiyama
 
PDF
基本に戻ってInnoDBの話をします
yoku0825
 
PDF
いつやるの?Git入門 v1.1.0
Masakazu Matsushita
 
PDF
雑なMySQLパフォーマンスチューニング
yoku0825
 
PDF
ヤフー社内でやってるMySQLチューニングセミナー大公開
Yahoo!デベロッパーネットワーク
 
PPTX
Apache Avro vs Protocol Buffers
Seiya Mizuno
 
PDF
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
Koichiro Matsuoka
 
PDF
PostgreSQL 15 開発最新情報
Masahiko Sawada
 
PPTX
世界一わかりやすいClean Architecture
Atsushi Nakamura
 
PPTX
【修正版】Django + SQLAlchemy: シンプルWay
Takayuki Shimizukawa
 
PDF
コンテナとimmutableとわたし。あとセキュリティ。(Kubernetes Novice Tokyo #15 発表資料)
NTT DATA Technology & Innovation
 
PDF
VPCのアウトバウンド通信を制御するためにおさえておきたい設計ポイント
Takuya Takaseki
 
PDF
Djangoフレームワークのユーザーモデルと認証
Shinya Okano
 
PDF
OpenID Connect入門
土岐 孝平
 
PDF
Serverless時代のJavaについて
Amazon Web Services Japan
 
CI/CDって何が良いの?〜言うてるオレもわからんわ〜 #DevKan
Kazuhito Miura
 
Dockerからcontainerdへの移行
Akihiro Suda
 
Docker Compose 徹底解説
Masahito Zembutsu
 
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Akihiro Suda
 
C# 8.0 非同期ストリーム
信之 岩永
 
MySQLとPostgreSQLの基本的なレプリケーション設定比較
Shinya Sugiyama
 
基本に戻ってInnoDBの話をします
yoku0825
 
いつやるの?Git入門 v1.1.0
Masakazu Matsushita
 
雑なMySQLパフォーマンスチューニング
yoku0825
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
Yahoo!デベロッパーネットワーク
 
Apache Avro vs Protocol Buffers
Seiya Mizuno
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
Koichiro Matsuoka
 
PostgreSQL 15 開発最新情報
Masahiko Sawada
 
世界一わかりやすいClean Architecture
Atsushi Nakamura
 
【修正版】Django + SQLAlchemy: シンプルWay
Takayuki Shimizukawa
 
コンテナとimmutableとわたし。あとセキュリティ。(Kubernetes Novice Tokyo #15 発表資料)
NTT DATA Technology & Innovation
 
VPCのアウトバウンド通信を制御するためにおさえておきたい設計ポイント
Takuya Takaseki
 
Djangoフレームワークのユーザーモデルと認証
Shinya Okano
 
OpenID Connect入門
土岐 孝平
 
Serverless時代のJavaについて
Amazon Web Services Japan
 

Similar to Using ngx_lua / lua-nginx-module in pixiv (20)

PDF
Openresty
ogawatti
 
PDF
環境構築自動化ツールのご紹介
Etsuji Nakai
 
PDF
Azure IaaS update (2018年6月~7月 発表版)
Takamasa Maejima
 
PDF
第2回 松本勉強会 2012 05 25 - apache2.4とmod_lua
Ryosuke MATSUMOTO
 
PPTX
ネットワークエンジニアのための Puppet / Chef
npsg
 
PDF
OpenStack Atlanta Summit Report: Neutron, Nova and design summit sessions
Akihiro Motoki
 
PDF
Personal Cloud Automation
Etsuji Nakai
 
PDF
AlibabaCloudではじめるKubernetes
Shinya Mori (@mosuke5)
 
PDF
Windows エンジニア向け sql server on linux のためのスキルアップデート
Masayuki Ozawa
 
KEY
Lxc on cloud
Yukihiko SAWANOBORI
 
PPTX
Seastar:高スループットなサーバアプリケーションの為の新しいフレームワーク
Takuya ASADA
 
PDF
成長を加速する minne の技術基盤戦略
Hiroshi SHIBATA
 
PPT
Osoljp201210 oi swift
Noriyasu Sakaue
 
PDF
第1回 松本勉強会 2012 05 11 - 公開版
Ryosuke MATSUMOTO
 
PDF
Dockerの仕組みとIIJ社内での利用例
maebashi
 
PPTX
SpringOne 2015 報告会 - Lattice + Spring Cloud Netflix
Tommy Ludwig
 
PDF
Jenkins study jenkins build-cicdi
昌桓 李
 
PDF
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
JustSystems Corporation
 
PPTX
自宅ラック勉強会 2.2 夏のZabbix特別教室 ~構築編~
真乙 九龍
 
PDF
20130714 July Tech Festa 日本CloudStackユーザー会
samemoon
 
Openresty
ogawatti
 
環境構築自動化ツールのご紹介
Etsuji Nakai
 
Azure IaaS update (2018年6月~7月 発表版)
Takamasa Maejima
 
第2回 松本勉強会 2012 05 25 - apache2.4とmod_lua
Ryosuke MATSUMOTO
 
ネットワークエンジニアのための Puppet / Chef
npsg
 
OpenStack Atlanta Summit Report: Neutron, Nova and design summit sessions
Akihiro Motoki
 
Personal Cloud Automation
Etsuji Nakai
 
AlibabaCloudではじめるKubernetes
Shinya Mori (@mosuke5)
 
Windows エンジニア向け sql server on linux のためのスキルアップデート
Masayuki Ozawa
 
Lxc on cloud
Yukihiko SAWANOBORI
 
Seastar:高スループットなサーバアプリケーションの為の新しいフレームワーク
Takuya ASADA
 
成長を加速する minne の技術基盤戦略
Hiroshi SHIBATA
 
Osoljp201210 oi swift
Noriyasu Sakaue
 
第1回 松本勉強会 2012 05 11 - 公開版
Ryosuke MATSUMOTO
 
Dockerの仕組みとIIJ社内での利用例
maebashi
 
SpringOne 2015 報告会 - Lattice + Spring Cloud Netflix
Tommy Ludwig
 
Jenkins study jenkins build-cicdi
昌桓 李
 
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
JustSystems Corporation
 
自宅ラック勉強会 2.2 夏のZabbix特別教室 ~構築編~
真乙 九龍
 
20130714 July Tech Festa 日本CloudStackユーザー会
samemoon
 
Ad

Recently uploaded (7)

PDF
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PDF
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
PDF
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
PDF
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
PDF
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
PDF
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
PDF
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
Ad

Using ngx_lua / lua-nginx-module in pixiv

  • 1. / 30 Using ngx_lua in pixiv Harukasan a.k.a MICHII Shunsuke 2013-06-24
  • 2. / 30 はるかさん インフラ部所属 2年目 Nginx / Apache / MySQL / MongoDB Kyototycoon / Solr / Traffic Server / Fluentd Capistrano / Ruby on Rails / Macbook Air / Vim 2
  • 3. / 303 • about pixiv Image Cluster • ngx_lua • directives in nginx.conf • nginx api in lua scripts • ex. code from pixiv Image Cluster Agenda
  • 5. / 305  Front Cache Cluster Image Store  SSD-RAID0     HDD SSD Thumbnailbig size Memory DEVICEpeak: 1k req/sec 10Gbps x20 x20
  • 6. / 306  Front Cache Cluster Image Store PRODUCT Nginx with tmpfs Traffic Server Apache / NginxNginx
  • 8. / 308 • embeds Lua/LuaJIT into Nginx • has 100% non-blocking API • has many libraries provided by OpenResty • memcached, mysql, redis, etc. ngx_lua
  • 9. / 309 # load from /etc/nginx/scripts/?.lua and default root lua_package_path "/etc/nginx/scripts/?.lua;;"; server { listen 80; # GET /fact?a=4 -> 24 (4! = 4 * 3 * 2 * 1) location /fact { content_by_lua " local val = 1 for i = 2, ngx.var.arg_a do val *= i; end "; } # same code in file location /fact_script { content_by_lua_file "fact.lua"; } }
  • 10. / 3010 Directives in nginx.conf • *_by_lua, *_by_lua_file • init_by_lua • rewrite_by_lua • access_by_lua • content_by_lua 設定読み込み rewrite処理 access処理 bodyの生成処理
  • 11. / 3011 init_by_lua <code> masterが設定をロードするタイミングで実行する init_by_lua " memcached = require 'resty.memcached' "; server { ! listen 8888; ! default_type 'text/plain'; ! location /init_by { ! ! content_by_lua " ! ! local hello = memcached::get('Hello'); ... ! ! "; ! } }
  • 12. / 3012 server { listen 80; # GET /sum?a=2&b=3 -> 5 location /sum { set_by_lua $sum " return tonumber(ngx.var.arg_a) + tonumber(ngx.var.arg_b) "; echo $sum; } } set_by_lua $res <code> 実行したコードの返値を$resにセットする
  • 13. / 3013 server rewrite find config rewrite post rewrite pre-access access post-access try files content logging Request rewrite/access/content_by_lua サーバーコンテキストのrewrite 該当するlocation configを探す locationのrewrite処理 ファイルへのアクセス try_fileの処理 bodyの生成 ログ書き込み access_by_lua content_by_lua rewrite_by_lua rewriteに関連する処理 アクセス制御 bodyの操作
  • 14. / 3014 server { listen 8888; location /rewrite_by { rewrite_by_lua "ngx.var.toggle = true"; if ($toggle) { rewrite / /index_second.html; } } } rewrite_by_lua <code> rewriteの前に指定したコードを実行する
  • 15. / 3015 server { listen 80; # GET /access_by?status=404 => 404 Not Found location /access_by { access_by_lua "ngx.exit(ngx.var.arg_status)"; } } access_by_lua <code> access phaseに指定したコードを実行する
  • 16. / 3016 # GET /hello location /hello { content_by_lua " ngx.say('Hello, from lua') "; } content_by_lua <code> responseを生成するコードを実行する
  • 17. / 3017 Directives in nginx.conf • LuaスクリプトでNginxの各動作を制御できる • HTTPで必要な各フェーズでフックできる • rewrite • access control • content generation ここまで8分
  • 18. / 3018 Nginx API in lua scripts • generate content • variables and shared tables • access memcached / MySQL
  • 19. / 3019 location /var { content_by_lua " ngx.say('Hello, from lua!') "; } ngx.say content bodyに文字列を出力する location /var { access_by_lua " ngx.exit(418) "; # i'm a teapot } ngx.exit 指定したステータスコードを返す
  • 20. / 3020 location /var { set $a "alpha"; rewrite_by_lua "ngx.var.b = ngx.var.a .. 'beta'"; echo $b; } ngx.var.* ngx.ctx.* location /ctx { access_by_lua "ngx.ctx.foo = 74"; rewrite_by_lua "ngx.ctx.foo = ngx.ctx.foo + 5"; content_by_lua "ngx.say('foo: ' .. ngx.ctx.foo)"; } Nginxの変数にアクセスする リクエスト中に共有されるテーブル
  • 21. / 3021 ngx.shared.* shared memoryテーブル http { lua_shared_dict foo 10m; server { location /shared-set { content_by_lua " local foo = ngx.shared.foo foo:set(ngx.var.arg_key, ngx.var.arg_val) "; } location /shared-get { content_by_lua " local foo = ngx.shared.foo ngx.say(foo:get(ngx.var.arg_key)) "; } } }
  • 22. / 3022 Regular Expressions • ngx.re.match • ngx.re.gmatch • ngx.re.sub • ngx.re.gsub
  • 23. / 3023 local matches, err = ngx.re.match("key=val", "([^=]+)=(.+)") ngx.re.match ngx.re.sub matches[0] => "key=val" matches[1] => "key" matches[2] => "val" local newstr,n,err = ngx.re.sub("Hello,lua","lua", "nginx") newstr = "Hello,nginx"
  • 24. / 3024 • OpenResty • lua-resty-memcached github.com/agentzh/lua-resty-memcached • lua-resty-mysql github.com/agentzh/lua-resty-mysql • ngx.socketを使って実装されている Access to memcached/MySQL
  • 25. / 3025 Nginx API in lua scripts • 簡単な処理を書くには十分な関数が 提供されている • 正規表現 • ハッシュ(md5, sha1) • ソケット • OpenRestyを使うとmemcachedへのアクセス とかも簡単
  • 26. / 3026 Example code from pixiv Image Cluster
  • 27. / 3027 Kyototycoon Logical Delete Nginx 200 404 /img01.png 200 /img02.png 200 /img03.png 404 /img04.png 200   GET /img01.png GET /img03.png 404
  • 28. / 3028 Logical Delete local memcached = require "resty.memcached" local uri = ngx.var.request_uri local memc = memcached:new() local val, flags, err = memc:get(request_uri) if val and val ~= "200" then exit(tonumber(val)) end logical_delete.lua location / { access_by_lua_file logical_delete.lua; }
  • 29. / 3029 Conclusion • Nginxだけで簡単な処理を実現できる • アクセス制御とかインプレッション計測 とかには便利そう • 高速で省メモリ • メンテナンスコストを抑えられる
  • 30. / 3030 References HTTPLuaModule - Nginx Wiki http://wiki.nginx.org/HttpLuaModule chaoslawful/lua-nginx-module - Github https://github.com/chaoslawful/lua-nginx-module