XNUMX 幎åãTarantool ã䜿ã£ãŠã¿ãŸããããããŸããããŸããã§ããã ããããæè¿ç§ã¯ãŠã§ãããŒãéå¬ããHadoop ãš MapReduce ã®ä»çµã¿ã«ã€ããŠè©±ããŸããã ããã§åœŒãã¯ç§ã«è³ªåãããŸãããããã®ã¿ã¹ã¯ã« Tarantool ã䜿çšããªãã®ã¯ãªãã§ãã?ã
奜å¥å¿ãããç§ã¯ãã®ãããžã§ã¯ãã«æ»ã£ãŠææ°ããŒãžã§ã³ããã¹ãããããšã«ããŸããããããŠä»åã¯ãã®ãããžã§ã¯ãããšãŠãæ°ã«å ¥ããŸããã ããã§ã¯ãTarantool ã§ç°¡åãªã¢ããªã±ãŒã·ã§ã³ãäœæããããŒãããŠããã©ãŒãã³ã¹ããã§ãã¯ããæ¹æ³ã説æããŸããããã§ããã¹ãŠãããã«ç°¡åã§åªããŠãããããããã§ãããã
ã¿ã©ã³ããŒã«ãšã¯
Tarantool ã¯ãèªèº«ãè¶ é«éããŒã¿ããŒã¹ãšããŠäœçœ®ã¥ããŠããŸãã ããã«å¿ èŠãªããŒã¿ã眮ãããšãã§ããŸãã ããã«ãããããã¬ããªã±ãŒãããŠã·ã£ãŒããã (ã€ãŸããèšå€§ãªéã®ããŒã¿ãè€æ°ã®ãµãŒããŒã«åå²ãããããã®çµæãçµåãã) ããšã§ããã©ãŒã«ã ãã¬ã©ã³ããªãã¹ã¿ãŒéæ¥ç¶ãäœæããŸãã
XNUMX çªç®ã«ãããã¯ã¢ããªã±ãŒã·ã§ã³ ãµãŒããŒã§ãã ãã®äžã«ã¢ããªã±ãŒã·ã§ã³ãäœæããããããŒã¿ãæäœããããããšãã°ãç¹å®ã®ã«ãŒã«ã«åŸã£ãŠããã¯ã°ã©ãŠã³ãã§å€ãã¬ã³ãŒããåé€ãããã§ããŸãã ããŒã¿ãåŠçãã Http ãµãŒããŒã Tarantula ã§çŽæ¥äœæã§ããŸãããã®éãæå®ããããã«æ°ããããŒã¿ãæžã蟌ã¿ããã¹ãŠããã¹ã¿ãŒã«éå ããŸãã
ç§ã¯ã圌ããã©ã®ããã«ã㊠300 è¡ã®ã¡ãã»ãŒãž ãã¥ãŒãäœæãããã«ã€ããŠã®èšäºãèªã¿ãŸãããããã¯åã«ããŒã¹ãããŠæ¥ãã§ããã ãã§ããã20 ç§ããã 000 ã¡ãã»ãŒãžã®æäœããã©ãŒãã³ã¹ããããŸãã ããã§ã¯ãå®éã«æ¹å転æããŠãéåžžã«å€§èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸããPostgreS ã®å Žåã®ããã«ãããã¯ã¹ãã¬ãŒãžã§ã¯ãããŸããã
ãã®èšäºã§ã¯ããã®ãµãŒããŒã®ãããªãã®ã«ã€ããŠãç°¡åã«èª¬æããŠã¿ãŸãã
ã€ã³ã¹ããŒã«
ãã¹ãã®ããã«ã20 ã€ã®æšæºä»®æ³ãã·ã³ (18.04 GB ããŒã ãã©ã€ããUbuntu 2) ãèµ·åããŸããã 4 ã€ã®ä»®æ³ CPU ãš XNUMX GB ã®ã¡ã¢ãªã
Tarantool ãã€ã³ã¹ããŒã«ããŸããbash ã¹ã¯ãªãããå®è¡ãããããªããžããªãè¿œå ã㊠apt get install Tarantool ãå®è¡ããŸãã ã¹ã¯ãªãããžã®ãªã³ã¯ - (curl -L
ã¿ã©ã³ããŒã«ctl â Tarantula ã€ã³ã¹ã¿ã³ã¹ã管çããããã®ã¡ã€ã³ ã³ãã³ãã
/etc/tarantool - ããã«å
šäœã®æ§æããããŸãã
var/log/tarantool - ããã«ãã°ããããŸãã
var/lib/tarantool â ããŒã¿ã¯ããã«ãããã€ã³ã¹ã¿ã³ã¹ã«åå²ãããŸãã
ãinstance-availableããã©ã«ããŒãšãinstance-enableããã©ã«ããŒããããŸãããã®ãã©ã«ããŒã«ã¯ãèµ·åããããã®ãå«ãŸããŠããŸããlua ã³ãŒããå«ãã€ã³ã¹ã¿ã³ã¹æ§æãã¡ã€ã«ãããã«ã¯ããªãã¹ã³ããããŒãã䜿çšå¯èœãªã¡ã¢ãªãŒããããŒã« ãšã³ãžã³ã®èšå®ãèµ·åæã«å®è¡ãããã³ãŒããèšè¿°ãããŠããŸãããµãŒããŒãã·ã£ãŒãã£ã³ã°ããã¥ãŒãå€ãããŒã¿ã®åé€ãªã©ã
ã€ã³ã¹ã¿ã³ã¹ã¯ PostgreS ãšåãããã«åäœããŸãã ããšãã°ãç°ãªãããŒãã§ãã³ã°ããããŒã¿ããŒã¹ã®ã³ããŒãè€æ°å®è¡ãããšããŸãã è€æ°ã®ããŒã¿ããŒã¹ ã€ã³ã¹ã¿ã³ã¹ã XNUMX å°ã®ãµãŒããŒäžã§èµ·åãããç°ãªãããŒãã§ãã³ã°ããŠããããšãããããŸããã ãããã¯å®å šã«ç°ãªãèšå®ãæã€å ŽåããããŸããXNUMX ã€ã®ã€ã³ã¹ã¿ã³ã¹ã¯ XNUMX ã€ã®ããžãã¯ãå®è£ ããXNUMX çªç®ã®ã€ã³ã¹ã¿ã³ã¹ã¯å¥ã®ããžãã¯ãå®è£ ããŸãã
ã€ã³ã¹ã¿ã³ã¹ç®¡ç
Tarantula ã€ã³ã¹ã¿ã³ã¹ã管çã§ãã tarantoolctl ã³ãã³ãããããŸãã ããšãã°ãtarantoolctl check ãµã³ãã«ã¯æ§æãã¡ã€ã«ããã§ãã¯ããæ§æãšã©ãŒããªããã°ãã¡ã€ã«ã¯æ£åžžã§ãããšå€æããŸãã
ã€ã³ã¹ã¿ã³ã¹ã®ã¹ããŒã¿ã¹ã確èªã§ããŸã (tarantoolctl ã¹ããŒã¿ã¹ã®äŸ)ã åæ§ã«ãéå§ãåæ¢ãåèµ·åãè¡ãããšãã§ããŸãã
ã€ã³ã¹ã¿ã³ã¹ãå®è¡ãããããXNUMX ã€ã®æ¹æ³ã§ã€ã³ã¹ã¿ã³ã¹ã«æ¥ç¶ã§ããŸãã
1. 管çã³ã³ãœãŒã«
ããã©ã«ãã§ã¯ãTarantool ã¯ãœã±ãããéããéåžžã® ASCII ããã¹ããããã«éä¿¡ãã㊠Tarantool ãå¶åŸ¡ããŸãã ã³ã³ãœãŒã«ãžã®æ¥ç¶ã¯åžžã«ç®¡çãŠãŒã¶ãŒã§è¡ãããèªèšŒã¯è¡ãããªããããTarantula ã管çããããã«ã³ã³ãœãŒã« ããŒããå€éšåããå¿ èŠã¯ãããŸããã
ãã®æ¹æ³ã䜿çšããŠæ¥ç¶ããã«ã¯ãTarantoolctl ã«ã€ã³ã¹ã¿ã³ã¹åãå ¥åããå¿ èŠããããŸãã ãã®ã³ãã³ãã¯ã³ã³ãœãŒã«ãèµ·åãã管çè ãŠãŒã¶ãŒãšããŠæ¥ç¶ããŸãã ã³ã³ãœãŒã« ããŒãã¯æ±ºããŠå€éšã«å ¬éããªãã§ãã ããããŠããã ãœã±ãããšããŠæ®ããŠããããšããå§ãããŸãã ããããã°ããœã±ãããžã®æžã蟌ã¿ã¢ã¯ã»ã¹æš©ãæã€ãŠãŒã¶ãŒã ãã Tarantula ã«æ¥ç¶ã§ããããã«ãªããŸãã
ãã®ã¡ãœããã¯ç®¡çäžã®å¿ èŠããããŸãã ããŒã¿ãæäœããã«ã¯ãXNUMX çªç®ã®æ¹æ³ã§ãããã€ã㪠ãããã³ã«ã䜿çšããŸãã
2. ãã€ããªãããã³ã«ã䜿çšããŠç¹å®ã®ããŒãã«æ¥ç¶ãã
èšå®ã«ã¯ãå€éšéä¿¡çšã®ããŒããéã listen ãã£ã¬ã¯ãã£ããå«ãŸããŠããŸãã ãã®ããŒãã¯ãã€ã㪠ãããã³ã«ã§äœ¿çšãããããã§èªèšŒãæå¹ã«ãªããŸãã
ãã®æ¥ç¶ã«ã¯ãtarantoolctl connect to ããŒãçªå·ã䜿çšãããŸãã ããã䜿çšãããšããªã¢ãŒã ãµãŒããŒã«æ¥ç¶ããèªèšŒã䜿çšããããŸããŸãªã¢ã¯ã»ã¹æš©ãäžããããšãã§ããŸãã
ããŒã¿èšé²ãšããã¯ã¹ã¢ãžã¥ãŒã«
Tarantool ã¯ããŒã¿ããŒã¹ãšã¢ããªã±ãŒã·ã§ã³ ãµãŒããŒã®äž¡æ¹ã§ãããããããŸããŸãªã¢ãžã¥ãŒã«ããããŸãã ç§ãã¡ã¯ããã¯ã¹ ã¢ãžã¥ãŒã«ã«èå³ããããŸããããã¯ããŒã¿ã®æäœãå®è£ ããŠããŸãã ããã¯ã¹ã«äœããæžã蟌ããšãTarantool ã¯ããŒã¿ããã£ã¹ã¯ã«æžã蟌ãã ããã¡ã¢ãªã«ä¿åããããããã«å¯ŸããŠäœãä»ã®åŠçãå®è¡ããŸãã
èšé²
ããšãã°ãbox ã¢ãžã¥ãŒã«ã«ç§»åããbox.once é¢æ°ãåŒã³åºããŸãã ããã«ããããµãŒããŒã®åæåæã« Tarantool ãã³ãŒããå®è¡ããããã«ãªããŸãã ããŒã¿ãä¿åããã¹ããŒã¹ãäœæããŸãã
local function bootstrap()
local space = box.schema.create_space('example')
space:create_index('primary')
box.schema.user.grant('guest', 'read,write,execute', 'universe')
-- Keep things safe by default
-- box.schema.user.create('example', { password = 'secret' })
-- box.schema.user.grant('example', 'replication')
-- box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end
ãã®åŸãããŒã¿ãæ€çŽ¢ã§ãããã©ã€ã㪠ã€ã³ããã¯ã¹ (primary) ãäœæããŸãã ããã©ã«ãã§ã¯ããã©ã¡ãŒã¿ãäœãæå®ããªãå Žåãåã¬ã³ãŒãã®æåã®ãã£ãŒã«ãããã©ã€ã㪠ã€ã³ããã¯ã¹ã«äœ¿çšãããŸãã
次ã«ãã²ã¹ã ãŠãŒã¶ãŒã«èš±å¯ãäžãããã®äžã§ãã€ã㪠ãããã³ã«çµç±ã§æ¥ç¶ããŸãã ã€ã³ã¹ã¿ã³ã¹å šäœã§èªã¿åããæžã蟌ã¿ãå®è¡ãèš±å¯ããŸãã
åŸæ¥ã®ããŒã¿ããŒã¹ãšæ¯èŒãããšãããã§ã¯ãã¹ãŠãéåžžã«ã·ã³ãã«ã§ãã ç§ãã¡ã«ã¯ã¹ããŒã¹ãã€ãŸãããŒã¿ãåã«ä¿åãããé åããããŸãã åã¬ã³ãŒãã¯ã¿ãã«ãšåŒã°ããŸãã MessagePack ã«ããã±ãŒãžåãããŠããŸãã ããã¯éåžžã«åªãã圢åŒã§ãããã€ããªã§ãããå æã¹ããŒã¹ãå°ãªããªããŸãã18 ãã€ãã«å¯Ÿã㊠27 ãã€ãã§ãã
圌ãšäžç·ã«ä»äºãããã®ã¯ãšãŠã䟿å©ã§ãã ã»ãŒãã¹ãŠã®è¡ããã¹ãŠã®ããŒã¿ ã¬ã³ãŒãã«ãŸã£ããç°ãªãåãå«ããããšãã§ããŸãã
Box.space ã³ãã³ãã䜿çšããŠããã¹ãŠã®ã¹ããŒã¹ã衚瀺ã§ããŸãã ç¹å®ã®ã€ã³ã¹ã¿ã³ã¹ãéžæããã«ã¯ãbox.space ã®äŸãäœæããããã«é¢ããå®å šãªæ å ±ãååŸããŸãã
Tarantool ã«ã¯ãMemory ãš Vinyl ãšãã XNUMX ã€ã®å èµãšã³ãžã³ããããŸãã ã¡ã¢ãªã¯ãã¹ãŠã®ããŒã¿ãã¡ã¢ãªã«ä¿åããŸãã ãããã£ãŠããã¹ãŠãç°¡åãã€è¿ éã«æ©èœããŸãã ããŒã¿ã¯ãã£ã¹ã¯ã«ãã³ãããããã°å è¡æžã蟌ã¿ã¡ã«ããºã ãããã®ã§ããµãŒããŒãã¯ã©ãã·ã¥ããŠãäœã倱ãããããšã¯ãããŸããã
Vinyl ã¯ãç§ãã¡ã«ãšã£ãŠãã銎æã¿ã®ãã圢åŒã§ããŒã¿ããã£ã¹ã¯ã«ä¿åããŸããã€ãŸããç§ãã¡ã®ã¡ã¢ãªãããå€ãã®ããŒã¿ãä¿åã§ããTarantula ã¯ããããã£ã¹ã¯ããèªã¿åããŸãã
ããã§ã¯ã¡ã¢ãªã䜿çšããŸãã
unix/:/var/run/tarantool/example.control> box.space.example
---
- engine: memtx
before_replace: 'function: 0x41eb02c8'
on_replace: 'function: 0x41eb0568'
ck_constraint: []
field_count: 0
temporary: false
index:
0: &0
unique: true
parts:
- type: unsigned
is_nullable: false
fieldno: 1
id: 0
space_id: 512
type: TREE
name: primary
primary: *0
is_local: false
enabled: true
name: example
id: 512
...
unix/:/var/run/tarantool/example.control>
玢åŒïŒ
ãã©ã€ã㪠ã€ã³ããã¯ã¹ããªããã°äœãæ©èœããªããããã©ã®ã¹ããŒã¹ã«å¯ŸããŠããã©ã€ã㪠ã€ã³ããã¯ã¹ãäœæããå¿ èŠããããŸãã ä»ã®ããŒã¿ããŒã¹ãšåæ§ã«ãæåã®ãã£ãŒã«ãã§ããã¬ã³ãŒã ID ãäœæããŸãã
éšåïŒ
ããã§ã¯ãã€ã³ããã¯ã¹ãäœã§æ§æãããŠãããã瀺ããŸãã ãã㯠18 ã€ã®éšåã§æ§æãããŸãã䜿çšããæåã®ãã£ãŒã«ãã¯ç¬Šå·ãªãã¿ã€ãã§ãããæ£ã®æŽæ°ã§ãã ããã¥ã¡ã³ãããèŠããŠããéããåãåŸãæ倧æ°ã¯ XNUMX 京ã§ãã ããã¯å€ãã§ãã
次ã«ãinsert ã³ãã³ãã䜿çšããŠããŒã¿ãæ¿å ¥ããŸãã
unix/:/var/run/tarantool/example.control> box.space.example:insert{1, 'test1', 'test2'}
---
- [1, 'test1', 'test2']
...
unix/:/var/run/tarantool/example.control> box.space.example:insert{2, 'test2', 'test3', 'test4'}
---
- [2, 'test2', 'test3', 'test4']
...
unix/:/var/run/tarantool/example.control> box.space.example:insert{3, 'test3'}
---
- [3, 'test3']
...
unix/:/var/run/tarantool/example.control> box.space.example:insert{4, 'test4'}
---
- [4, 'test4']
...
unix/:/var/run/tarantool/example.control>
æåã®ãã£ãŒã«ãã¯äž»ããŒãšããŠäœ¿çšããããããäžæã§ããå¿ èŠããããŸãã åã®æ°ã«å¶éããªããããå¿ èŠãªã ãããŒã¿ãæ¿å ¥ã§ããŸãã ãããã¯ãäžã§èª¬æãã MessagePack 圢åŒã§æå®ãããŸãã
ããŒã¿åºå
次ã«ãselect ã³ãã³ãã䜿çšããŠããŒã¿ã衚瀺ã§ããŸãã
{1} ããŒãæŒã㊠Box.example.select ãæŒããšãç®çã®ãšã³ããªã衚瀺ãããŸãã ããŒãäžãããšãæã£ãŠãããã¹ãŠã®ã¬ã³ãŒãã衚瀺ãããŸãã ãããã¯ãã¹ãŠåã®æ°ãç°ãªããŸãããããã§ã¯ååãšããŠåã®æŠå¿µã¯ãªãããã£ãŒã«ãçªå·ããããŸãã
絶察ã«ããããéã®ããŒã¿ãååšããå¯èœæ§ããããŸãã ããšãã°ãXNUMX çªç®ã®ãã£ãŒã«ãã§æ€çŽ¢ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãæ°ããã»ã«ã³ã㪠ã€ã³ããã¯ã¹ãäœæããŸãã
box.space.example:create_index( âsecondaryâ, { type = âTREEâ, unique = false, parts = {{field = 2, type =âstringâ} }})
Create_index ã³ãã³ãã䜿çšããŸãã
ãããã»ã«ã³ããªãšåŒã³ãŸãããã
ãã®åŸããã©ã¡ãŒã¿ãæå®ããå¿ èŠããããŸãã ã€ã³ããã¯ã¹ã®çš®é¡ã¯ TREE ã§ãã äžæã§ã¯ãªãå¯èœæ§ãããããããUnique = falseããšå ¥åããŸãã
次ã«ãã€ã³ããã¯ã¹ãã©ã®éšåã§æ§æãããŠãããã瀺ããŸãã Field ã¯ã€ã³ããã¯ã¹ããã€ã³ããããã£ãŒã«ãã®çªå·ã§ãããæååã¿ã€ããæå®ããŸãã ãããŠãããäœæãããŸããã
unix/:/var/run/tarantool/example.control> box.space.example:create_index('secondary', { type = 'TREE', unique = false, parts = {{field = 2, type = 'string'}}})
---
- unique: false
parts:
- type: string
is_nullable: false
fieldno: 2
id: 1
space_id: 512
type: TREE
name: secondary
...
unix/:/var/run/tarantool/example.control>
ããã§ã次ã®ããã«åŒã³åºãããšãã§ããŸãã
unix/:/var/run/tarantool/example.control> box.space.example.index.secondary:select('test1')
---
- - [1, 'test1', 'test2']
...
ä¿åãã
ã€ã³ã¹ã¿ã³ã¹ãåèµ·åããããŒã¿ãå床åŒã³åºãããšãããšãããŒã¿ãååšããªãããšãããããŸãããã¹ãŠã空ã§ãã ããã¯ãTarantool ããã§ãã¯ãã€ã³ããäœæããããŒã¿ããã£ã¹ã¯ã«ä¿åããããã«çºçããŸããã次ã®ä¿åãŸã§äœæ¥ãåæ¢ãããšããã¹ãŠã®æäœã倱ãããŸããæåŸã®ãã§ãã¯ãã€ã³ã (ããšãã°ãXNUMX æéå) ããå埩ããããã§ãã
åžžã« 20 GB ããã£ã¹ã¯ã«ãã³ãããã®ã¯åŸçã§ã¯ãªããããæ¯ç§ä¿åããããšãã§ããŸããã
ãã®ç®çã®ããã«ããã°å è¡æžã蟌ã¿ã®æŠå¿µãçºæãããå®è£ ãããŸããã ãã®æ©èœã䜿çšãããšãããŒã¿ãå€æŽããããã³ã«ãå°ããªå è¡æžã蟌ã¿ãã° ãã¡ã€ã«ã«ãšã³ããªãäœæãããŸãã
ãã§ãã¯ãã€ã³ããŸã§ã®åãšã³ããªãä¿åãããŸãã ãããã®ãã¡ã€ã«ã«ã¯ããµã€ãºãèšå®ããŸã (ããšãã°ã64 MB)ã ãã£ã±ãã«ãªããšãXNUMX çªç®ã®ãã¡ã€ã«ãžã®é²é³ãéå§ãããŸãã åèµ·ååŸãTarantool ã¯æåŸã®ãã§ãã¯ãã€ã³ããã埩å ãããåæ¢ãããŸã§ä»¥éã®ãã¹ãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ãããŒã«ãªãŒããŒãããŸãã
ãã®ãããªèšé²ãå®è¡ããã«ã¯ãbox.cfg èšå® (example.lua ãã¡ã€ã«å
) ã§ãªãã·ã§ã³ãæå®ããå¿
èŠããããŸãã
wal_mode = âwriteâ;
ããŒã¿äœ¿çšé
ãããŸã§ã«æžããå 容ã䜿çšãããšãTarantula ã䜿çšããŠããŒã¿ãä¿åã§ããããŒã¿ããŒã¹ãšããŠéåžžã«é«éã«æ©èœããŸãã ãããŠä»ãã±ãŒãã®é£Ÿãä»ãã¯ãããããã¹ãŠã䜿ã£ãŠã§ããããšã§ãã
ã¢ããªã±ãŒã·ã§ã³ã®äœæ
ããšãã°ãã¿ã©ã³ãã¥ã©çšã«æ¬¡ã®ã¢ããªã±ãŒã·ã§ã³ãæžããŠã¿ãŸãããã
ã¹ãã€ã©ãŒã®äžã®ã¢ããªã±ãŒã·ã§ã³ãåç §ããŠãã ãã
box.cfg {
listen = '0.0.0.0:3301';
io_collect_interval = nil;
readahead = 16320;
memtx_memory = 128 * 1024 * 1024; -- 128Mb
memtx_min_tuple_size = 16;
memtx_max_tuple_size = 128 * 1024 * 1024; -- 128Mb
vinyl_memory = 128 * 1024 * 1024; -- 128Mb
vinyl_cache = 128 * 1024 * 1024; -- 128Mb
vinyl_max_tuple_size = 128 * 1024 * 1024; -- 128Mb
vinyl_write_threads = 2;
wal_mode = "write";
wal_max_size = 256 * 1024 * 1024;
checkpoint_interval = 60 * 60; -- one hour
checkpoint_count = 6;
force_recovery = true;
log_level = 5;
log_nonblock = false;
too_long_threshold = 0.5;
read_only = false
}
local function bootstrap()
local space = box.schema.create_space('example')
space:create_index('primary')
box.schema.user.create('example', { password = 'secret' })
box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
box.schema.user.create('repl', { password = 'replication' })
box.schema.user.grant('repl', 'replication')
end
-- for first run create a space and add set up grants
box.once('replica', bootstrap)
-- enabling console access
console = require('console')
console.listen('127.0.0.1:3302')
-- http config
local charset = {} do -- [0-9a-zA-Z]
for c = 48, 57 do table.insert(charset, string.char(c)) end
for c = 65, 90 do table.insert(charset, string.char(c)) end
for c = 97, 122 do table.insert(charset, string.char(c)) end
end
local function randomString(length)
if not length or length <= 0 then return '' end
math.randomseed(os.clock()^5)
return randomString(length - 1) .. charset[math.random(1, #charset)]
end
local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')
local httpd = http_server.new('0.0.0.0', 8080, {
log_requests = true,
log_errors = true
})
local router = http_router.new()
local function get_count()
local cnt = box.space.example:len()
return cnt
end
router:route({method = 'GET', path = '/count'}, function()
return {status = 200, body = json.encode({count = get_count()})}
end)
router:route({method = 'GET', path = '/token'}, function()
local token = randomString(32)
local last = box.space.example:len()
box.space.example:insert{ last + 1, token }
return {status = 200, body = json.encode({token = token})}
end)
prometheus = require('prometheus')
fiber = require('fiber')
tokens_count = prometheus.gauge("tarantool_tokens_count",
"API Tokens Count")
function monitor_tokens_count()
while true do
tokens_count:set(get_count())
fiber.sleep(5)
end
end
fiber.create(monitor_tokens_count)
router:route( { method = 'GET', path = '/metrics' }, prometheus.collect_http)
httpd:set_router(router)
httpd:start()
æåãå®çŸ©ããããŒãã«ã lua ã§å®£èšããŸãã ãã®ãã¬ãŒãã¯ãã©ã³ãã ãªæååãçæããããã«å¿ èŠã§ãã
local charset = {} do -- [0-9a-zA-Z]
for c = 48, 57 do table.insert(charset, string.char(c)) end
for c = 65, 90 do table.insert(charset, string.char(c)) end
for c = 97, 122 do table.insert(charset, string.char(c)) end
end
ãã®åŸãé¢æ°randomStringã宣èšããæ¬åŒ§å ã«é·ãã®å€ãæå®ããŸãã
local function randomString(length)
if not length or length <= 0 then return '' end
math.randomseed(os.clock()^5)
return randomString(length - 1) .. charset[math.random(1, #charset)]
end
次ã«ãhttp ã«ãŒã¿ãŒãš http ãµãŒããŒã Tarantula ãµãŒã㌠(JSON) ã«æ¥ç¶ããã¯ã©ã€ã¢ã³ãã«éä¿¡ããŸãã
local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')
ãã®åŸããã¹ãŠã® http ãµãŒã㌠ã€ã³ã¿ãŒãã§ã€ã¹ã®ããŒã 8080 ã§éå§ãããã¹ãŠã®ãªã¯ãšã¹ããšãšã©ãŒããã°ã«èšé²ããŸãã
local httpd = http_server.new('0.0.0.0', 8080, {
log_requests = true,
log_errors = true
})
次ã«ãGET ã¡ãœããã«ãããªã¯ãšã¹ããããŒã 8080 /count ã«å°çããå Žåã«ã200 è¡ããé¢æ°ãåŒã³åºãããã«ãroute ã宣èšããŸãã ã¹ããŒã¿ã¹ (404ã403ãXNUMXããŸãã¯æå®ãããã®ä») ãè¿ããŸãã
router:route({method = 'GET', path = '/count'}, function()
return {status = 200, body = json.encode({count = get_count()})}
end)
æ¬æã§ã¯ json.encode ãè¿ãããã®äžã§ count ãš getcount ã瀺ããŸããããã¯åŒã³åºãããããŒã¿ããŒã¹å ã®ã¬ã³ãŒãã®æ°ã瀺ããŸãã
第2ã®æ¹æ³
router:route({method = 'GET', path = '/token'}, function()
local token = randomString(32)
local last = box.space.example:len()
box.space.example:insert{ last + 1, token }
return {status = 200, body = json.encode({token = token})}
end)
åã®ã©ãã« router:route({ã¡ãœãã = 'GET', ãã¹ = '/token'}, function() é¢æ°ãåŒã³åºããŠããŒã¯ã³ãçæããŸãã
ã²ã ããŒã«ã«ããŒã¯ã³ = ã©ã³ãã æåå(32) 32 æåã®ã©ã³ãã ãªæååã§ãã
åããªã㊠local last = box.space.example:len() æåŸã®èŠçŽ ãåãåºããŸãã
ãããŠåã®äžã§ box.space.example:insert{ æåŸ + 1, ããŒã¯ã³ } ããŒã¿ãããŒã¿ããŒã¹ã«æžã蟌ã¿ãŸããã€ãŸããID ã 1 ãã€å¢ããã ãã§ããã¡ãªã¿ã«ãããã¯ãã®äžåšçšãªæ¹æ³ã ãã§å®è¡ã§ããããã§ã¯ãããŸããã ã¿ã©ã³ãã¥ã©ã«ã¯ãã®ã·ãŒã±ã³ã¹ããããŸãã
ããã«ããŒã¯ã³ãæžã蟌ã¿ãŸãã
ãããã£ãŠãã¢ããªã±ãŒã·ã§ã³ã XNUMX ã€ã®ãã¡ã€ã«ã«èšè¿°ããŸããã ããã§ããŒã¿ãçŽæ¥æäœã§ããããã¯ã¹ ã¢ãžã¥ãŒã«ãé¢åãªäœæ¥ããã¹ãŠå®è¡ããŸãã
http ããªãã¹ã³ããŠããŒã¿ãæäœããã¢ããªã±ãŒã·ã§ã³ãšããŒã¿ã®äž¡æ¹ããã¹ãŠ XNUMX ã€ã®ã€ã³ã¹ã¿ã³ã¹å ã«ãããŸãã ãããã£ãŠããã¹ãŠãéåžžã«æ©ãèµ·ãããŸãã
ãŸããhttp ã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ããŸãã
ããæ¹ã¯ã¹ãã€ã©ãŒã®äžãèŠãŠãã ãã
root@test2:/# tarantoolctl rocks install http
Installing http://rocks.tarantool.org/http-scm-1.src.rock
Missing dependencies for http scm-1:
checks >= 3.0.1 (not installed)
http scm-1 depends on checks >= 3.0.1 (not installed)
Installing http://rocks.tarantool.org/checks-3.0.1-1.rockspec
Cloning into 'checks'...
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 28 (delta 1), reused 16 (delta 1), pack-reused 0
Receiving objects: 100% (28/28), 12.69 KiB | 12.69 MiB/s, done.
Resolving deltas: 100% (1/1), done.
Note: checking out '580388773ef11085015b5a06fe52d61acf16b201'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
No existing manifest. Attempting to rebuild...
checks 3.0.1-1 is now installed in /.rocks (license: BSD)
-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found TARANTOOL: /usr/include (found version "2.4.2-80-g18f2bc82d")
-- Tarantool LUADIR is /.rocks/share/tarantool/rocks/http/scm-1/lua
-- Tarantool LIBDIR is /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
version
-- Build files have been written to: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Scanning dependencies of target httpd
[ 50%] Building C object http/CMakeFiles/httpd.dir/lib.c.o
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: In function âtpl_termâ:
/usr/include/tarantool/lauxlib.h:144:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
(*(B)->p++ = (char)(c)))
~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: note: in expansion of macro âluaL_addcharâ
luaL_addchar(b, '\');
^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: note: here
default:
^~~~~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: In function âtpe_parseâ:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
type = TPE_TEXT;
~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: note: here
case TPE_LINECODE:
^~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: In function âhttpfast_parseâ:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
code = 0;
~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: note: here
case status:
^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: warning: this statement may fall through [-Wimplicit-fallthrough=]
state = message;
~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: note: here
case message:
^~~~
[100%] Linking C shared library lib.so
[100%] Built target httpd
[100%] Built target httpd
Install the project...
-- Install configuration: "Debug"
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 is now installed in /.rocks (license: BSD)
root@test2:/#
å®è¡ããã«ã¯ prometheus ãå¿ èŠã§ãã
root@test2:/# tarantoolctl rocks install prometheus
Installing http://rocks.tarantool.org/prometheus-scm-1.rockspec
Cloning into 'prometheus'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 19 (delta 2), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (19/19), 10.73 KiB | 10.73 MiB/s, done.
Resolving deltas: 100% (2/2), done.
prometheus scm-1 is now installed in /.rocks (license: BSD)
root@test2:/#
èµ·åããŠã¢ãžã¥ãŒã«ã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸã
root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive
{"token":"e2tPq9l5Z3QZrewRf6uuoJUl3lJgSLOI"}
root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive
{"token":"fR5aCA84gj9eZI3gJcV0LEDl9XZAG2Iu"}
root@test2:/# curl -D - -s http://127.0.0.1:8080/count
HTTP/1.1 200 Ok
Content-length: 11
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive
{"count":2}root@test2:/#
/count ã¯ã¹ããŒã¿ã¹ 200 ã瀺ããŸãã
/token ã¯ããŒã¯ã³ãçºè¡ãããã®ããŒã¯ã³ãããŒã¿ããŒã¹ã«æžã蟌ã¿ãŸãã
é床ããã¹ããã
50 ãªã¯ãšã¹ãã®ãã³ãããŒã¯ãå®è¡ããŠã¿ãŸãããã 競åãããªã¯ãšã¹ã㯠000 件ãããŸãã
root@test2:/# ab -c 500 -n 50000 http://127.0.0.1:8080/token
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests
Server Software: Tarantool
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /token
Document Length: 44 bytes
Concurrency Level: 500
Time taken for tests: 14.578 seconds
Complete requests: 50000
Failed requests: 0
Total transferred: 7950000 bytes
HTML transferred: 2200000 bytes
Requests per second: 3429.87 [#/sec] (mean)
Time per request: 145.778 [ms] (mean)
Time per request: 0.292 [ms] (mean, across all concurrent requests)
Transfer rate: 532.57 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 10 103.2 0 3048
Processing: 12 69 685.1 15 13538
Waiting: 12 69 685.1 15 13538
Total: 12 78 768.2 15 14573
Percentage of the requests served within a certain time (ms)
50% 15
66% 15
75% 16
80% 16
90% 16
95% 16
98% 21
99% 42
100% 14573 (longest request)
root@test2:/#
ããŒã¯ã³ãçºè¡ãããŸãã ãããŠç§ãã¡ã¯åžžã«ããŒã¿ãèšé²ããŠããŸãã ãªã¯ãšã¹ãã® 99% ã 42 ããªç§ã§åŠçãããŸããã ãããã£ãŠã3500 ã€ã®ã³ã¢ãš 2 GB ã®ã¡ã¢ãªãåããå°åãã·ã³ã§ã¯ã4 ç§ãããçŽ XNUMX 件ã®ãªã¯ãšã¹ããçºçããŸãã
çŽ 50000 ããŒã¯ã³ãéžæããŠããã®äŸ¡å€ã確èªããããšãã§ããŸãã
http ã ãã§ãªããããŒã¿ãåŠçããããã¯ã°ã©ãŠã³ãé¢æ°ãå®è¡ããããšãã§ããŸãã ããã«ãããŸããŸãªããªã¬ãŒããããŸãã ããšãã°ãæŽæ°æã«é¢æ°ãåŒã³åºããããäœãããã§ãã¯ãããã競åãä¿®æ£ãããã§ããŸãã
ã¹ã¯ãªãã ã¢ããªã±ãŒã·ã§ã³ãããŒã¿ããŒã¹ ãµãŒããŒèªäœã«çŽæ¥èšè¿°ã§ããäœã«ãå¶éããããä»»æã®ã¢ãžã¥ãŒã«ãæ¥ç¶ããä»»æã®ããžãã¯ãå®è£ ã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ ãµãŒããŒã¯å€éšãµãŒããŒã«ã¢ã¯ã»ã¹ããããŒã¿ãååŸããŠããŒã¿ããŒã¹ã«è¿œå ã§ããŸãã ãã®ããŒã¿ããŒã¹ã®ããŒã¿ã¯ä»ã®ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããŸãã
Tarantula ã¯ãããèªåçã«è¡ããããå¥ã®ã¢ããªã±ãŒã·ã§ã³ãäœæããå¿ èŠã¯ãããŸããã
çµè«
ããã¯å€§ããªäœåã®æåã®éšåã«ãããŸããã XNUMX çªç®ã®ãã®ã¯ãMail.ru ã°ã«ãŒãã®ããã°ã§éããªãå ¬éãããäºå®ã§ããããã®è³æã«ã¯å¿ ããã®ãªã³ã¯ãè¿œå ããŸãã
ãããã®ãã®ããªã³ã©ã€ã³ã§æ§ç¯ãããªã¢ã«ã¿ã€ã ã§è³ªåããã€ãã³ãã«åå ããããšã«èå³ãããå Žåã¯ãèŠèŽããŠãã ããã
ã¯ã©ãŠãã«ç§»è¡ããå¿
èŠãããå ŽåããŸãã¯ã€ã³ãã©ã¹ãã©ã¯ãã£ã«ã€ããŠè³ªåãããå Žåã¯ã
PS ã§ã¯æã« 2 åã®ç¡æç£æ»ãè¡ã£ãŠãããããããããªãã®ãããžã§ã¯ãããã®ãã¡ã® XNUMX ã€ãšãªãã§ãããã
åºæïŒ habr.com