ããã«ã¡ã¯ãHabrauserïŒ
ã ã¿ã©ã³ãã¥ã©ããŒã
㯠ãé«è² è·ã®ãããžã§ã¯ãã§ããŒã¿ãå¹æçã«äœ¿çšããããã®æŽå¯ãšå°éç¥èãå
±æã
ç¶ããŠããŸãã ä»æ¥ã¯ãTarantoolããããŒã€ã³ã¯ã³ãã§ããçç±ã解æããããšããŸããããŒã¿ããŒã¹ã ãã§ãªããã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãããã§ãã ãã¶ããTarantulaãLuaã§ã®ã¬ããªã±ãŒã·ã§ã³ãšã¹ãã¬ãŒãžããµããŒãããè¶
é«éã§æ°žç¶çãªã¡ã¢ãªå
ã¹ãã¬ãŒãžãšèãã人ãããã§ãããã Redisã®æçãåãåºããåçµããNode.jsãè¿œå ããGoã§è£å
ããŠããã
ç
®æ²žããŠãã5åéãã£ãããšèª¿çããŸãã ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã¯ãããšäœã®é¢ä¿ãããã®ã§ããããïŒ

å€ãã®äººãé©ãã§ãããããnginxãGoãNode.jsãRedisãMongoDBãTarantoolãªã©ã®åªãã補åã«ã¯ãã¢ãŒããã¯ãã£é¢ã§å€ãã®å
±éç¹ããããŸãã äœããã®æ¹æ³ã§é«æ§èœãããã¯ãŒã¯ãµãŒããŒãäœæããã«ã¯ãéããããã³ã°å
¥åºåãéåæã€ãã³ãåŠçãã¡ã¢ãªã®æäœããšã©ãŒåŠçããã°ãæªéãªã©ãæäŸããäžé£ã®ã©ã€ãã©ãªãå¿
èŠã§ãããã®ã©ã³ã¿ã€ã ãšã³ãžã³ã¯éåžžãããªãè€éãªããšã§ãããããŸããŸãªã·ã¹ãã ã®åºç€ãšäœã¬ãã«ã®ããã°ã©ãã³ã°ã¹ãã«ãæ·±ãç解ããå¿
èŠããããŸãã
TarantoolããŒã ã®ç§ãã¡ã¯ãéåæã€ãã³ãåŠçããã³ããããã³ã°I / OããŠãŒã¶ãŒç©ºéïŒãã¡ã€ããŒïŒã®ã°ãªãŒã³ã¹ã¬ãããå調ãã«ãã¿ã¹ã¯ãç¹æ®ãªã¡ã¢ãªã¢ãã±ãŒã¿ãŒã®ãã¡ããªãŒãªã©ãåããç¬èªã®ã©ã³ã¿ã€ã ãäœæããéåžžã«é·ãéã®ããæ©ã¿ãŸããã Goãšæãã¢ãŒããã¯ãã£çã«äŒŒãŠããŸãïŒæãè
ãåãèããæã£ãŠããŸãïŒããçŽç²ãªCã®ã©ã€ãã©ãªã®åœ¢ã§ã®ã¿ã§ãããã®åºç€ã®ãããã§ããã³ãããã®äžã«ãDBMSããäœæããããšãã§ããŸãããèšæ¶ åžå Žã®ãããããªã³ãã ããæç¹ã§ãã¢ããªã±ãŒã·ã§ã³éçºè
ã«ç¡å¶éã®èªç±ãäžããã¹ãã¢ãããã·ãŒãžã£ã§ããŒã¿ããŒã¹ã¯ãšãªãå®è¡ã§ããã ãã§ãªããããŒã«ãããå
šäœãå®å
šã«äœ¿çšã§ããããã«ããããšã«ããŸããã ããŒã¿ããŒã¹ããçŽæ¥ã¯ã©ãŠããµãŒãã¹ããHTTPçµç±ã§JSONãååŸããã³è§£æããã®ã¯ç°¡åã§ãã DBMSã§RESTãµãŒãã¹ãçŽæ¥å®è¡ããŸã-ãé¡ãããŸãã å€æ°ã®ãµãŒããŒã§ããŒã¿ãååŸããã¯ãšãªã䞊ååŠçããŸã-åé¡ãããŸããïŒ ãã¹ãŠã®æ©èœãšããŒã«ã¯éçºè
ã®æã«ãããŸãïŒ éçºè
ãéçºè
ãéçºè
ïŒ
ã¿ã©ã³ããŒã«ã§XãYãZãäœãæ¹æ³ã¯ïŒ

Tarantoolã®äœçŸãã®Redisã³ãã³ãããããã¥ãŒãæå¹æéããŒã¿ãpub / subãmultigetããŸãã¯ä»ã®äœãããããã©ãããããå°ããããŸãã ããããã¿ã©ã³ããŒã«ã«ã¯ããã¯ãããŸãããããã§ã¯ãããŸããã§ããïŒãã¿ãã³ã¿ã³ïŒã ãã®ãã¹ãæŸæ£ããå°ãç°ãªãã¢ãããŒããæäŸããŸãã ãåç¥ã®ããã«ãç·ã«éãããããšããã€ãã¯æºè
¹ã«ãªããé£ãæ¹ãæããã°ããã€ãæºè
¹ã«ãªããŸãã Tarantoolã«ã¯ããŒã«ïŒãé£ãç«¿ãïŒãçšæãããŠãããããã䜿çšããŠããã¿ãŒã³ããã¿ãŒã³ã®ã«ããŽãªã«ç±æ¥ãããã®ãªã©ãããŸããŸãªåé¡ã解決ã§ããŸãã å€ãããŒã¿ã®èªååé€-Luaã®ããã¯ã°ã©ãŠã³ããã¡ã€ããŒã ç¹å®ã®æ¡ä»¶äžã§ã®è€æ°ã®ããŒãã«ããã®ãã«ãã²ãã-Luaã®2è¡ã JSON圢åŒã§ããŒã¿ãè¿ã-WebãµãŒããŒã¢ãžã¥ãŒã«ãããŒã¿ããŒã¹ã«çŽæ¥ããŒãããŸãã
ç®±ããåºããŠèããŠãã ãã ïŒ
TarantoolãæäŸããããŒã«ã®çš®é¡ãèŠãŠã¿ãŸãããã
- ãã¡ã€ã㌠-å調ãã«ãã¿ã¹ã¯ãšãã£ãã«ïŒGoã®å ŽåïŒã
- socket ã fio-éåæã®éããããã³ã°ãœã±ãããšãã¡ã€ã«I / Oã
- json / msgpack / yaml-ããŒã¿ã¢ã³ããã«ãŒ;
- mysql / pg /äœã§ã-MySQLã®ã¯ã©ã€ã¢ã³ããã¿ã©ã³ãã¥ã©èªäœããã®PostgreSQL;
- net.box-ã¿ã©ã³ãã¥ã©èªäœããã¿ã©ã³ãã¥ã©ãžã®ã¯ã©ã€ã¢ã³ãã
- http-ããªããã£ãHTTPãµãŒããŒããã³ã¯ã©ã€ã¢ã³ãã
- tap-ã¢ããªã±ãŒã·ã§ã³ãšã¢ãžã¥ãŒã«ã®ãã¹ãã
- ã³ã³ãœãŒã« -ãµãŒããŒã¹ããŒã¿ã¹ã®æ€æ»ãã³ãŒãã®ãããããŒããèšå®ã®å€æŽããã®å Žã§;
- log-ã€ãã³ããã®ã³ã°ãlogrotate;
- initã¹ã¯ãªãããRPM / DEBããã±ãŒãžãå±éããŒã«ãªã©
ãã®
ããã¯ã¹ã¯ãã¢ããªã±ãŒã·ã§ã³ã®åãã¢ãã¬ã¹ç©ºéã§çŽæ¥åäœãããã©ã³ã¶ã¯ã·ã§ã³ãµããŒããšãã«ããã¹ã¿ãŒã¬ããªã±ãŒã·ã§ã³ãåãã
è¶
é«éãã«ããšã³ãžã³ããŒã¿ããŒã¹ã§ãã
èå³æ·±ãããšã«ã3å±€ã¢ãŒããã¯ãã£ããããŸããïŒ

ãå¥ã®ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒïŒNode.jsãPHPãPythonãªã©ïŒãšDBMSïŒRedisãMongoDBãªã©ïŒã§ã¯ãªãããã¹ãŠã®ããžãã¹ããžãã¯ãããŒã¿ããŒã¹ã«è»¢éããããšãå床ææ¡ããŸããïŒã ããããç§ãã¡ã¯å®å®ã®åºç€ã
䟵ããŠãã
ããã§ã¯ãããŸããã ããå°ãå®çšçã«èŠãŠã¿ãŸãããã
ãã©ãŠã¶ãŒã§
ã¹ããŒã¹ã¢ããªã±ãŒã·ã§ã³ã
çŽæ¥çŽæ¥æžã蟌ãããšãã§ããå ŽåããµãŒããŒåŽã¯ããŒã¿ã®ä¿åãšåŠçã®ããã«ã»ãšãã©ã®éšåãç¶æããŸããããã©ãŠã¶ãŒã¯AJAXãä»ããŠå¿
èŠãªãã¹ãŠã®æ
å ±ãåçã«èŠæ±ããã³æŽæ°ã§ããŸãã ãã®ã·ããªãªã§ã¯ãã¢ããªã±ãŒã·ã§ã³ãµãŒããŒïŒPHP / Node / Go / PythonïŒã¯äœãããŸããïŒ ããŒã¿ããŒã¹ããã®å¿çãåŸ
æ©ããŠããŠãããã«ãã¹ãŠãnginxã®JSON圢åŒã§æäŸããã®ã¯ã¢ã€ãã«ã§ããïŒ ãã ãããã©ã³ã¶ã¯ã·ã§ã³ãéããŠããããããã¯ãŒã¯çµç±ã§ããŒã¿ããŒã¹ããããŒã¿ãããŠã³ããŒããããããã®äžéšã®ãã£ãŒã«ããã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã«å€æŽããæŽæ°ãããŒã¿ããŒã¹ã«éãè¿ãããã©ã³ã¶ã¯ã·ã§ã³ãéããŠçµæãnginxã«è¿ãå¿
èŠããããŸãã ããã«è¿œå ã®ãããã¯ãŒã¯ã©ãŠã³ãããªããããã³ãŠãŒã¶ãŒç©ºé<->ã«ãŒãã«<->ãŠãŒã¶ãŒç©ºéã®åãæ¿ããäœåè²»ãããŸããïŒ ããã§ããããŒã¿ããŒã¹ã¯ãããšãã°ããã¯ããã®ä»ã®éãã¡ã«ããºã ã䜿çšããã³ã¹ãã§ãéããŠããåãã©ã³ã¶ã¯ã·ã§ã³ã®ããŒã¿ã®å®å
šãªèªã¿åããã¥ãŒããµããŒãããå¿
èŠããããŸãã 1ã€ã®ãã¬ãŒããã5ã€ã®ã¬ã³ãŒããéžæããå¥ã®ãã¬ãŒãã®2ã€ã®ã¬ã³ãŒããæŽæ°ããçµæãRESTãµãŒãã¹ã«è¿ãããã«ãããããã¹ãŠãå¿
èŠã§ããïŒ
ãã®çš®ã®ãã€ã¯ããµãŒãã¹ã®ããã«ãTarantulaã¯DBMSå
ã§ããŒã¿èªäœã®ããé£ã«ã¹ãã¬ãŒãžãæžã蟌ãããã®
é£ãç«¿ãæäŸããŠããŸãã
tarantool-httpã¢ãžã¥ãŒã«ãš
nginx_tarantool_upstream㯠ãTarantulaããRESTãµãŒãã¹ãç°¡åã«æŽçãããµãŒãã¹ã¢ãŒããã¯ãã£ãç°¡çŽ åããå°çšã®ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã®åœ¢ã§äžèŠãªãªã³ã¯ãåé€ããŸãã åæã«ããããžã§ã¯ãã®æãè² è·ã®é«ãéšåã®ã¿ããã€ã¯ããµãŒãã¹ãšããŠéžæã§ããããããã®æ¹æ³ã§ã¢ããªã±ãŒã·ã§ã³å
šäœãæžãçŽãããšãç³ãåºã人ã¯ããŸãããåŸæ¥ã®ãœãªã¥ãŒã·ã§ã³ã®çç£æ§ããŒãžã³ã¯ååã§ã¯ãããŸããã æ®ãã«ã€ããŠã¯ãããŸããŸãªããã°ã©ãã³ã°èšèªã®ã³ãã¯ã¿ãä»ããŠãæ±çšDBMSãšåãTarantoolã䜿çšã§ããŸãã
çµæ§ã§ãããã«ã¢ã¯ããŸãïŒïŒ

ãLuaã§ã®æžãæ¹ãããããŸããã ãããŠããã®ãããªããã°ã©ããŒã¯ã©ãã§å
¥æã§ããŸããïŒã
ãããã¯ã«ãªããªãã§ãã ãã ïŒ LuaïŒãã«ãã¬ã«ã®æïŒã¯3ã€ã®ã³ããã¯ãšåããããç°¡åãªèšèªã§ããã10å·»
ã®èè
ã®
åéãããäœåãç 究ããäœæ¥ãå¿
èŠãšããŸããã å°äžéã§åºåãèŠã代ããã«äŸãèŠãŠã¿ãŸãã-ãããŠãããªãã¯ãã§ã«ã³ãŒã
ã奪ãå§ããããšãã§ããŸãã Mail.Ru Groupã§ã¯ãLuaããã·ãŒãžã£ã¯ãC / C ++ããã°ã©ããŒã ãã§ãªããPythonãPerlãRubyãããã³JSéçºè
ã«ãã£ãŠåæ§ã«æåè£ã«èšè¿°ãããŠããŸãã ãããããªãLuaãªã®ãïŒ Tarantoolã¯ãéçºè
ã«åé¡ã解決ã§ãããã¥ãŒãªã³ã°å®å
šãªé«ã¬ãã«ããã°ã©ãã³ã°èšèªãæäŸããŸãã ç§ãã¡ã®ããŒãã¢ã€ãã³ã¯
PL / SQL ã
XML ã
YAMLããã³
iniãã¡ã€ã« ïŒç§ã¯ç¥ãèš±ããŠïŒã§ããã°ã©ãã³ã°ãããŠ
ããªããšããŸãããã ããã«ãLuaã¯éåžžã«ã·ã³ãã«ã§
éåžžã«é«éã§ãã ãããžã§ã¯ãã§èšèªæ©èœã®10ïŒ
ã䜿çšããå¿
èŠããããã©ããã«ã€ããŠãLuaã«ã¯è°è«ããããŸããã
ãšããã§ãTarantoolã«ã¯
ãåäŸã®ãªãããã©ãŒãã³ã¹ãšãçè«çã«ã¯ä»ã®èšèªã䜿çšããæ©èœãå®çŸã§ãã
APIããã
ãŸã ã ããã«ã€ããŠã¯æ¬¡ã®ã·ãªãŒãºã§è©³ãã説æããŸããåæããªãã§ãã ããã
ãã£ãŠã¿ããïŒ

tarantool.org/download.htmlãã
Tarantoolãã€ã³ã¹ããŒã«ããŸãã ãµã€ãã®ãªããžããªã«ã¯ãäž»èŠãªLinuxãã£ã¹ããªãã¥ãŒã·ã§ã³ã®ãã€ããªããã±ãŒãžãšãFreeBSDã®ããŒãããã³OS Xã®brewããããŸããã€ã³ã¹ããŒã«åŸã
tarantool
ã§tarantoolã³ãã³ããå
¥åããŸãã
roman@book:~$ tarantool tarantool: version 1.6.8-123-gbe2ce21 type 'help' for interactive help tarantool>
ã€ã³ã¿ãŒããªã¿ãŒã§ã¯ãä»»æã®Luaã³ãŒããå
¥åã§ããçµæã¯ã³ã³ãœãŒã«ã«èªã¿åãå¯èœãªåœ¢åŒïŒYAMLïŒã§è¡šç€ºãããŸãã
tarantool> 2 + 2 --- - 4 ... tarantool> { name = "Roman", gender = "male" } --- - name: Roman gender: male ... tarantool> print('Hello') Hello --- ...
ãã¹ãŠåããã®ãã¹ã¯ãªãããšããŠå¥ã®ãã¡ã€ã«ã«æžãããšãã§ããŸãã
BashãPythonããŸãã¯Rubyãšåæ§ã«ã¹ã¯ãªãããå®è¡ããŸãã
roman@desktop:~$ edit ololo.lua roman@desktop:~$ chmod a+x ololo.lua roman@desktop:~$ ./ololo.lua Hello world!
Tarantoolã¯ãã¹ã¯ãªããã¬ãã«ã§Lua 5.1ããã³LuaJITãšå®å
šã«äºææ§ããããããããã€ã³çœ®æãšããŠäœ¿çšã§ããŸãã Luaã®ãã¹ãŠã®ã¢ãžã¥ãŒã«ã¯Tarantoolã§åäœããŸãã
box.cfg{}
é¢æ°ã¯ãçµã¿èŸŒã¿ããŒã¿ããŒã¹ïŒããã¯ã¹ïŒãæ§æããã³å®è¡ããŸãããã®åŸãããŒãã«ïŒã¹ããŒã¹ïŒãäœæããã¯ãšãªãå®è¡ã§ããŸãã
tarantool> box.cfg {} [cut] tarantool> space = box.schema.space.create('test') [cut] tarantool> box.space.test:create_index('primary', { type = 'tree', parts = { 1, 'num' }}) [cut] tarantool> box.space.test:insert({48, 'some data', { key = 'value', key2 = 'value2' }}) --- - [48, 'some data', {'key': 'value', 'key2': 'value2'}] ... tarantool> box.space.test:select() --- - - [48, 'some data', {'key': 'value', 'key2': 'value2'}] ...
ããã§ïŒCTRL + DãŸãã¯
os.exit(0)
ïŒã€ã³ã¿ã©ã¯ãã£ãã³ã³ãœãŒã«ãåæ¢ãããšããã£ã¬ã¯ããªã«æ°ãã* .snapã* .xlogãã¡ã€ã«ã衚瀺ãããŸãã ãããã®ãã¡ã€ã«ã¯ãRAMå
ã®ããŒã¿ããŒã¹ã®æ°žç¶æ§ã確ä¿ããããã«äœ¿çšãããŸãã
tarantool
ããã¹ãŠã®ããŒã¿
tarantool
埩å
ãããŸãã
tarantool> box.cfg{} --- ... tarantool> box.space.test:select() --- - - [48, 'some data', {'key': 'value', 'key2': 'value2'}] ...
次ã«ããã£ãšè€éãªãã®ãè©ŠããŠã¿ãŸãããïŒã¡ã€ã³ããŒãžã®äŸïŒïŒ
#!/usr/bin/env tarantool box.cfg{}
éå§ããã«ã¯ã
tarantool-httpã¢ãžã¥ãŒã«ãå¿
èŠã§ããããã¯ãããã±ãŒãžãŸãã¯GitHubããé
ä¿¡ã§ããŸãã ã¹ã¯ãªããã¯æåã®èµ·åæã«
hosts
ããŒãã«ãäœæãããã®åŸHTTPãµãŒããŒãèµ·åããŸããããã«ãããåIPã¢ãã¬ã¹ã®ã«ãŠã³ã¿ãŒãã/ãã§ã€ã³ã¯ãªã¡ã³ãããããã¹ãŠã®ã¢ãã¬ã¹ãJSON圢åŒã§ã¯ã©ã€ã¢ã³ãã«è¿ãããŸãã nginxãµãŒãã¹ã®åã«çœ®ãã®ãç°¡åã§ãã ãšããã§ã
try.tarantool.org㯠Tarantoolèªäœã§èšè¿°ãããŠããŸãã ç§
ãã¡èªèº«ããµããã³ã
é£ã¹ ãéçºè
ã®ç掻ãããè¯ãããããšããŠããŸãã
æ¬çªãžã®å±é

æ¬çªãµãŒããŒã§åçŽãªã¢ããªã±ãŒã·ã§ã³ããã¹ãããæè¯ã®æ¹æ³ã¯äœã§ããïŒ çµå±ã®ãšãããã³ã³ãœãŒã«ã§ãã¬ã€ããããšãšãããããã¹ãŠãæŠéã«æå
¥ããããšã¯ãŸã£ããå¥ã®ããšã§ãã
ãã¹ãŠãã·ã³ãã«ã§ãã ã¹ã¯ãªããã
/etc/tarantool/instances.enabled/myapp.lua
転éããinitçšã®æ¢è£œã®ãŠãŒãã£ãªãã£ïŒ
tarantoolctl start myapp
ãŸãã¯
service tarantool restart
ïŒã§å®è¡ããŸãã ããŸãããïŒ ãã ïŒ
ä»»æã®æ°ã®ã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸããinitã·ã¹ãã èªäœãå¿
èŠãªæ°ã®TarantoolããŒã¢ã³ãèµ·åããããããç£èŠããŸãã ç©çã³ã¢ããããããã«å°ãªãã¿ã©ã³ãã¥ã©ãèµ·åããããšããå§ãããŸãã ãã®ã¢ãããŒãã¯ãåäžã®ãµãŒããŒã§æé«ã®ããã©ãŒãã³ã¹ãæäŸãã
æ°çŸäžãã«ã
ç¯çŽããŸãã ããã»ã¹ãªã¹ãã§ãã¢ããªã±ãŒã·ã§ã³ã®ååãæã€ããŒã¢ã³ãç°¡åã«èŠã€ããããšãã§ããŸãã ãã°ãã¡ã€ã«ã¯ããã©ã«ãã§
/var/log/tarantool/myapp.log
æžã蟌ãŸããããŒã¿ã¯
/var/lib/tarantool/myapp/
ã«ä¿åãããpidãã¡ã€ã«ã¯
/run/tarantool
æžã蟌ãŸããŸãã ã€ãŸãããã¹ãŠããæ°ã«å
¥ãã®ãã£ã¹ããªãã¥ãŒã·ã§ã³ã§æå³ãããšããã«ãªããŸãã
ãã³ãã¬ãŒãã䜿çšããŠãRPMããã³DEBããã±ãŒãžããã«ãã§ããŸãã
䟿å©ãªæ©èœã®äžã§ãã³ã³ãœãŒã«ãåäœäžã®ããŒã¢ã³ã«æ¥ç¶ããŠç¶æ
ãã€ã³ãã
tarantoolctl enter myapp
ãããã®å Žã§ã³ãŒããå€æŽã§ããããã«ãã
tarantoolctl enter myapp
ã³ãã³ããå¥ã«æ³šæãã䟡å€ããããŸãã ãŸãã
box.cfg({listen = 3313 })
ãä»ããŠãä»ã®ããã°ã©ãã³ã°èšèªããã¬ãŒã ã¯ãŒã¯ã®ã³ãã¯ã¿ãšæ¥ç¶ããããã®ãããã¯ãŒã¯ããŒããéãããšãã§ããŸãïŒå
šäžçã®ç§©åºãå£ããªããšçŽæããŸããïŒïŒ
次ã¯ïŒ
次ã®ã·ãªãŒãºã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¢ãžã¥ãŒã«ã¢ãŒããã¯ãã£ã確ä¿ãããã¹ããšç¶ç¶çãªã³ãŒãçµ±åãæŽçããæ¹æ³ã詳现ã«èª¬æããŸãã 1ã€ã®ç©çã³ã¢ã§æ¯ç§æ倧6Mã®ãªã¯ãšã¹ããåŠçããããã«Tarantulaãæºåããããã®ç§å¯ã®ããŠããŠãæããã«ãªããŸãã
質åãã³ã¡ã³ãããåŸ
ã¡ããŠããŸãã
Z. S. 1æ28æ¥ã«ã
å°äžéé§
Airportã«ããMail.Ru Groupã®
æå
端ã®ãªãã£ã¹ã§2åç®ã®Tarantool Meetupãéå¬ããŸãã äŒè°ã§ã¯ãç§ãã¡ã®ããŒã ãšã¿ã©ã³ãã¥ã©ã®å€éšãŠãŒã¶ãŒã®äž¡æ¹ããæ°ããæŽå¯ãåŸãããŸãã
ç»é²åŸãå
¥å Žæã¯ãã¹ãŠç¡æã§ãã ããªãã¯æ°åãè¯ãããããžã§ã¯ãã§Tarantoolãè©ŠããŠã¿ãããšæã£ãŠããŸãã