ã¯ããã«
Cloud Platforméšã®pddgã§ãã2024幎ããµããŒã€ã³ã¿ãŒã³ã·ãããéå¬ãããã©ãããã©ãŒã ïŒèªç€Ÿåºç€ïŒã³ãŒã¹ãšããŠ2åã®æ¹ãåãå ¥ããŸããã æšå¹Žã®æ§åã¯ä»¥äžããã芧ããã ããŸããèå³ãããã°æ¯éã芧äžããã
ä»åã¯åãå ¥ãããäºæ¹ã®ãã¡è€æ¬éœäººããïŒstatic-fujiïŒã«æ åœããŠããã ããæ€èšŒã®äžã§çºèŠããããçŽæçã§ãªãæåã«ã€ããŠãè€æ¬ããã«ããæ€èšŒçµæã瀟å¡ããŸãšãããã®ã«ãªããŸãã ãã®èšäºå ã§ã®æ€èšŒã®ã»ãšãã©ã¯ã€ã³ã¿ãŒã³çã§ããè€æ¬ããã«ãã£ãŠå®æœããããã®ã§ãããäžéšç€Ÿå¡ãã€ã³ã¿ãŒã³ã·ããå®äºåŸã«ãã®èšäºã®å·çã®ããã«çæããå³çãå«ãŸããŸãã
èæ¯
ãµã€ããŠãºã§ã¯ãçŸè¡ã®ã€ã³ãã©åºç€äžã§åäœããŠããã¢ããªã±ãŒã·ã§ã³ã»ããã«ãŠã§ã¢ãKubernetesããŒã¹ã®æ°åºç€ã«ç§»è¡ãããããžã§ã¯ããæšé²äžã§ãã ãã®äžã§ã課é¡ã®äžã€ãšããŠããããéçã³ã³ãã³ãïŒJavaScriptã»CSSãªã©ïŒã®é ä¿¡ãµãŒãã¹ãæããããŠããŸããçŸåšã¯nginxãå©çšããŠé ä¿¡ããŠããããã®ãã¹ãã®ããŒã«ã«ãã¡ã€ã«ã·ã¹ãã äžã«éçã³ã³ãã³ããã¢ããããŒãããŠããŸãã ãã®æ¹åŒã¯nginxã«ãã£ãŠå®å®ããŠé«éã«ã¬ã¹ãã³ã¹ãè¿ããã®ã§ãããã³ã³ãã³ãé ä¿¡ãµãŒããã¹ããŒããã«ã«ãªã£ãŠããŸããKubernetesãšã®çžæ§ãè¯ããªããšããåé¡ããããŸãã
ããã§ãæ°åºç€ã§ã¯Cephã®Object StorageãæŽ»çšããã¢ããªã±ãŒã·ã§ã³ããŒã ãæã€S3äºæã®ãªããžã§ã¯ããã±ããã«éçã³ã³ãã³ããã¢ããããŒãããããããnginxãååŸã»ãã£ãã·ã¥ããŠé ä¿¡ãããµãŒãã¹ãæ€èšããŠããŸãããããã«ããnginxèªäœã¯ã©ã®ãã±ãããèŠã«è¡ããã®ã¿ç¥ã£ãŠããã°ãããnginxã³ã³ããèªäœã¯ã¹ããŒãã¬ã¹ã«ã§ããŸãã
PoCãäœæãå®éã«åäœããããšã¯ããã£ããã®ã®ããã®æ§èœïŒã¬ã€ãã³ã·ã»ã¹ã«ãŒããããããŒãªã³ã°ã¢ããããŒãäžã®ããã©ãŒãã³ã¹ããããã¯ãšã³ãã®ãã±ãããžã©ããããã®ã¢ã¯ã»ã¹ãçºçãããçïŒãæ€èšŒããããã«ãã€ã³ã¿ãŒã³çãšããŠãžã§ã€ã³ããè€æ¬ãããžæ€èšŒãäŸé ŒããŸããã
nginxã®èšå®
ãã®PoCã«ãããŠnginxã«ã¯ä»¥äžã®æ§ãªèšå®ãæœããŠããŸãããã ããçŽæ¥çã«é¢ä¿ããããããªãšããã ãæç²ããŠãããä»ã®èšå®ã¯çç¥ããŠããŸãã
load_module /usr/lib/nginx/modules/ndk_http_module.so; http { # proxy cacheã®èšå®proxy_cache_path /cache/contents levels=2 # å®éã«äœ¿ãããŠããéçã³ã³ãã³ãã®ãµã€ãºãèŠãŠæ±ºããå€ keys_zone=cache:32M max_size=8G inactive=24h ; # proxy_cache_path ãšåãããã€ã¹äžã®ãã£ã¬ã¯ããªãæå®ããproxy_temp_path /cache/temp; # éçã³ã³ãã³ããé ä¿¡ããupstreamupstream origin { # ããã«ã¯å®éã®å€ãå ¥ãserver {{ORIGIN_HOST}}:{{ORIGIN_PORT}} max_fails=0; keepalive 16; } server { listen 8080; proxy_cache cache; # ãã£ãã·ã¥ã®ããŒã¯URLãšããã # GET ãš HEAD ãåäžèŠãããã®ã§ $request_method ã¯äœ¿ããªãã # ãŸããã¯ãšãªåŒæ°ã¯ç¡èŠãããproxy_cache_key"$scheme://$host$uri"; # 200 OK, 301 Moved Permanently, 302 Found, 303 See Other ã¯1ã¶æãã£ãã·ã¥ããproxy_cache_valid 200 301 302 303 2592000s; # ãã以å€ã®ãã¿ãŒã³ (400, 429, 500 ãªã©) # ãªãªãžã³ãµãŒããŒãå®ãããäžç¬ã ããã£ãã·ã¥ãããproxy_cache_valid any 1s; # ãã£ãã·ã¥ã®æŽæ°äžã«åã URL ã«å¯Ÿããåãåããããããã¯ããããšã§ã # ãªãªãžã³ãµãŒããŒãžã®åãåãããæžããã proxy_cache_lock on; # proxy_pass ã«ã¯ãšã¹ã±ãŒãæžã¿ã®ãã¹ãæž¡ãå¿ èŠãããã # ãããã$uri 㯠unescape ãããŠãããããLua ã䜿ã£ãŠãšã¹ã±ãŒãããªããã°ãªããªãã # # Q. ãªã $request_uri ã䜿ããªãã®ãïŒ # $request_uri ã¯å ¥åããããã¹ããã®ãŸãŸå ¥ã£ãŠããããããšã¹ã±ãŒãæžã¿ã®ã¯ãã§ããã # A. äŸãã°ã$request_uri ã "/../secretbucket/foobar" ã ã£ãå Žåãäžæ£ã«ä»ã®ãã±ããã«ã¢ã¯ã»ã¹ãããŠããŸãã # äžæ¹ $uri ã¯æ£èŠåæžã¿ã§ãããã /../ ã®ãããªéªæªãªæååãå«ãŸãªãã set_by_lua_block $escaped_path { -- ngx.escape_uri 㯠JavaScript ã® encodeURIComponent ãšç䟡ãªé¢æ°ã§ããã -- ããããããã§ã¯ JavaScript ã® encodeURI çžåœã®é¢æ°ãå¿ èŠãªã®ã§èªäœããå¿ èŠãããã -- (ææ°ã® lua-nginx-module ã«ã¯ãã®ãããªé¢æ°ãååšããããapt ã§å ¥ã lua-nginx-module ã¯æ®å¿µãªããå€ã) -- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/encodeURI local function encode_uri(uri) return uri:gsub("[^A-Za-z0-9;,/?:@&=+$_.!~*'()#-]", function(c) return string.format("%%%02X", string.byte(c)) end) end return encode_uri(ngx.var.uri) } location / { # ããã«ã¯å®éã®å€ãå ¥ã proxy_pass http://origin/{{BUCKET}}$escaped_path; } }
è² è·è©Šéšã®å®æœ
Grafana k6ãå©çšããŠè² è·è©Šéšã宿œããŠããã ããŸãããè² è·è©Šéšã®æ§æã¯ä»¥äžã®éãã§ãã
- ãã¹ãæé: 60s
- 1ç§ãããã®ãªã¯ãšã¹ãæ°ïŒrateïŒ: 100~10000åïŒåŸè¿°ã®è¡šã®éãïŒ
- ãã¹ãåæ°: ãªã¯ãšã¹ãæ°ããšã«1å
- 確èªããããŒã¿: ã¬ã€ãã³ã·ã®å¹³åïŒavgïŒãæå°å€ïŒminïŒãäžå€®å€ïŒmedïŒãæå€§å€ïŒmaxïŒãããŒã»ã³ã¿ã€ã«ïŒp(90)ãp(95)ïŒ
- ãªã¯ãšã¹ãã®éä¿¡ãè¡ãPodã®ãªãœãŒã¹
- CPU: 18 core
- ã¡ã¢ãª: 24GiB
- Nginx Podã®ãªãœãŒã¹
- 3ã¬ããªã«
- CPU: 4 core
- ã¡ã¢ãª: 18GiB
ãã¹ãå®è¡ããšã«Nginxã®Podã¯åäœæãããã£ãã·ã¥ã¯æ®çºãããŠè©ŠéšããŠããŸãããŸããCephã®æ§æãã¹ããã¯ãªã©ã¯è€éã§ããããšãæ¬èšäºã®çŸè±¡ãšçŽæ¥é¢ä¿ããªãããšããçç¥ãããŠãã ããã
ã¢ã¯ã»ã¹ãã察象ã®ãã¡ã€ã«ã¯ä»¥äžã®ã¹ã¯ãªããã§äœæããã10000åã®ããã¹ããã¡ã€ã«ã§ãäºã察象ã®ãã±ããã«ã¢ããããŒãããŠãããŸãã
output_dir="./static-contents"num_files=10000num_chars=10000mkdir-p"$output_dir"for i in$(seq -f "%05g"1$num_files)dofilename="file_$i.txt" base64 /dev/urandom | tr -dc'a-zA-Z0-9'| head -c$num_chars>"$output_dir/$filename"done
ãŸããk6ã®ã¹ã¯ãªããã¯ä»¥äžã®éãã§ãã
import http from'k6/http';import{ check }from'k6';// ã©ã³ãã ã«ã¢ã¯ã»ã¹ããããæ¢åã®ã¢ãžã¥ãŒã«ãå©çš// Ref: https://grafana.com/docs/k6/latest/javascript-api/jslib/utils/randomitem/import{ randomItem }from'/tmp/index.js'// 察象ã®Sericeã®ã¢ãã¬ã¹const baseUrl ='http://nginx.dev-static-poc.svc.cluster.local/';const fileNames =Array.from({length:10000},(_, i)=>`file_${String(i).padStart(5,'0')}.txt`);// fileåã¯"file_0XXXX.txt" ãšãªã£ãŠããïŒXã«ã¯0~9ã®æŽæ°ãå ¥ãïŒexportconst options ={scenarios:{contacts:{executor:'constant-arrival-rate',duration:'60s',timeUnit:'1s',preAllocatedVUs:200,// å®éšã®æ¡ä»¶ããšã«å€årate:10000,},},};exportdefaultfunction(){const params ={timeout:'10s',};const fileName =randomItem(fileNames);const url =`${baseUrl}/${fileName}`;const res = http.get(url, params);// ã¬ã¹ãã³ã¹ãè¿ã£ãŠããŠ200ã§ããããšã確èªcheck(res,{'status = 200':(r)=> r.status ===200});}
枬å®çµæ
ä»åèšå®ããç¯å²ã®ç§éãªã¯ãšã¹ãæ°ã§ã¯ã»ãšãã©ã®ã±ãŒã¹ã§ååé«éã«å¿çã§ããŠããŸããããã©ã®ãªã¯ãšã¹ãæ°ã®å Žåã§ãæãé ãã±ãŒã¹ã§ã¯500msãããã§ã¬ã€ãã³ã·ãé æã¡ããåŸåãããããšãããããŸãããã¿ã€ã ã¢ãŠããªã©ã®èšå®ãçããŸããããæ£ããStatus Code 200ãè¿ã£ãŠããŠããŸããã
rate | avg (ÎŒs) | min (ÎŒs) | med (ÎŒs) | max (ms) | p(90) (ms) | p(95) (ms) |
---|---|---|---|---|---|---|
100 | 14,040 | 285.41 | 7,300 | 500.45 | 29.17 | 43.77 |
500 | 3,450 | 230.08 | 1,570 | 499.71 | 2.54 | 14.41 |
1,000 | 2,220 | 212.39 | 394.25 | 500.64 | 1.95 | 3.87 |
10,000 | 950.15 | 173.91 | 269.17 | 507.99 | 0.42 | 1.43 |
以äžã¯åºåãããnginxã®ãã°äžã®ã¬ã¹ãã³ã¹ã¿ã€ã ãããã¹ããŒã¿ã¹ã³ãŒãå¥ã«æå€§å€ãæç³»åã§ãããããããã®ã§ãã瞊軞ãç§ã暪軞ã¯çµéæéã衚ããŸããå šãŠ200ãè¿ã£ãŠãããæåã®æ°ç§ã¯500msçšåºŠã®ã¬ã€ãã³ã·ã芳枬ããããã®åŸã¯ã»ãŒ0ã«è¿ã¥ããŠããŸãã*1ã
ãã®çµæãããupstreamã§ãããªããžã§ã¯ãã¹ãã¬ãŒãžããããŒã¿ãååŸããŠããéã«ã ã500msçšåºŠã®åŸ ã¡æéãçºçããå Žåããããšæšæž¬ããŸããããã®åŸä»åã®è©Šéšã«å«ãŸãããããŒã¿å šãŠã®ãã£ãã·ã¥ãå®äºãããšãnginxã¯éåžžã«é«éã«ã¬ã¹ãã³ã¹ãè¿ãããã«ãªããã®ãããªçµæã«ãªã£ãã®ã§ã¯ãªãããšèããŸããã
åœåããã¯upstreamã§ããCephã®ãªããžã§ã¯ãã¹ãã¬ãŒãžã®æ§èœã«ãªãããã®ç¹æ§ãããããã®ãããªã¬ã€ãã³ã·ãçºçããã±ãŒã¹ãå€ãã®ããšèããCephã®ãªããžã§ã¯ãã¹ãã¬ãŒãžãå ¬éãããšã³ããã€ã³ãã«çŽæ¥ãªã¯ãšã¹ãããè² è·è©Šéšãè¡ã£ãŠã¿ãŸããã
rate | avg (ÎŒs) | min (ÎŒs) | med (ÎŒs) | max (ms) | p(90) (ms) | p(95) (ms) |
---|---|---|---|---|---|---|
100 | 4,230 | 1,010 | 1,640 | 245.91 | 2.94 | 16.07 |
500 | 3,870 | 848.89 | 1,390 | 217.74 | 2.54 | 14.41 |
1,000 | 4450 | 826.12 | 1,350 | 279.08 | 7.17 | 20.03 |
10,000 | 19,960 | 813.8 | 17,830 | 342.66 | 32.53 | 40.17 |
ããããçµæãšããŠå®æž¬ããã¬ã€ãã³ã·ã¯æå€§ã§ã500msãŸã§éããããšã¯ãããŸããã§ãããnginxããã¯proxy_cache_lockã«ãã£ãŠCephãžã®ãªã¯ãšã¹ãæ°ã¯ãã®è² è·æ€èšŒãããå°ãªãããšãèãããšãCephããªã¯ãšã¹ããæããããªããªã£ãŠãããšãã£ãåé¡ãèãã«ãããšå€æããŸããã
ãããŸã§ã§ããããnginxã«åé¡ãããã§ãããããšãåãã£ãããããªãœãŒã¹éãªã©ã®èª¿æŽããããããŸããããåé¡ã¯è§£æ¶ããŸããã§ããããœãŒã¹ã³ãŒãã«ç®ãéãããšãproxy_cache_lockã®å®è£ ã«åé¡ãããããã«æããã®ã§ãã®èšå®ãå€ããŠã¿ããšãããåé¡ãè§£æ¶ããæ§åã芳枬ãããæå€§ã§ãcephã®ãªããžã§ã¯ãã¹ãã¬ãŒãžããã®ã¬ã¹ãã³ã¹ã¿ã€ã ã«è¿ãã¬ã€ãã³ã·ã§åãŸãããã«ãªããŸããã
rate | avg (ÎŒs) | min (ÎŒs) | med (ÎŒs) | max (ms) | p(90) (ms) | p(95) (ms) |
---|---|---|---|---|---|---|
100 | 6,970 | 225.36 | 1,690 | 254.06 | 19.43 | 30.85 |
500 | 5,970 | 216.04 | 1,640 | 293.99 | 17.88 | 27.02 |
1,000 | 2,870 | 193.73 | 395.05 | 246.27 | 2.35 | 10.4 |
10,000 | 656.6 | 169.22 | 265.43 | 224.46 | 0.42 | 1.4 |
æã ã®æ³å®ããŠããæå
枬å®ãããçµæã¯æã ã®æ³å®ãšã¯ç°ãªããã®ã§ãå®è£ æã«ã¯nginxã®proxy_cache_lockã¯Goã«ãããsingleflightã®ãããªæåããããšæ³å®ããŠããŸããã
ã€ãŸããåãããŒã«å¯ŸããŠè€æ°ã®ãªã¯ãšã¹ããæ¥ãå Žåãæåã®ãªã¯ãšã¹ããupstreamã«åãåãããè¡ãããã®çµæããã£ãã·ã¥ã«ä¿åããä»ã®ãªã¯ãšã¹ãã¯ãã®çµæãåŸ ã£ãŠãã£ãã·ã¥ããååŸãããšãããã®ã§ããããã«ãã䞊åãªã¯ãšã¹ããæ¥ãå Žåã«upstreamãžã®åãåããã1åã«ãªããããupstreamãžã®è² è·ãæããããã¬ã¹ãã³ã¹ã®é å»¶ãæå€§ã§upstreamãžã®æåã®åãåããã®ã¬ã€ãã³ã·ã¶ãã«ãªããšèããŠããŸããã
ããããæž¬å®çµæããproxy_cache_lockã®æåã¯æã ã®æ³å®ããŠãããã®ãšã¯ç°ãªãå¯èœæ§ãé«ãããšãããããŸããã
ãªã500msã§é æã¡ããã®ã
æªãããšçšãã proxy_cache_lockã®å®è£ ã«ã¯ã以äžã®ãããªã³ãŒãããããŸããã https://github.com/nginx/nginx/blob/fb89d50eeb19d42d83144ff76c80d20e80c41aca/src/http/ngx_http_file_cache.c#L404-L460
äžéšãæç²ããŸãã
timer = c->wait_time - now; ngx_add_timer(&c->wait_event, (timer > 500) ? 500 : timer);
ãªããããã«500msãããã§çºç«ããããªã¿ã€ããŒã®å®è£ ãå ¥ã£ãŠããããã«èŠããŸããâŠâŠ
https://nginx.org/en/docs/dev/development_guide.html#timer_events
The function ngx_add_timer(ev, timer) sets a timeout for an event, ngx_del_timer(ev) deletes a previously set timeout. The global timeout red-black tree ngx_event_timer_rbtree stores all timeouts currently set. The key in the tree is of type ngx_msec_t and is the time when the event occurs. The tree structure enables fast insertion and deletion operations, as well as access to the nearest timeouts, which nginx uses to find out how long to wait for I/O events and for expiring timeout events.
nginxã®éçºããã¥ã¡ã³ãã«ããã® ngx_add_timer
ã¯æå®ãããæéã§ã¿ã€ã ã¢ãŠããäœããã®åŠçãè¡ã颿°ã§ãããšæžãããŠããŸããproxy_cache_lockã®å®è£
ã§ã¯ wait_time - now
ãš 500
ã®ãã¡å°ããæ¹ãã¿ã€ããŒã«ã»ããããŠããããã500msã§ã¿ã€ã ã¢ãŠãããŠåŠçãçºç«ããããã§ãã
wait_timeãèšå®ããŠããã®ã¯å®ã¯0ã§åæåããããšããé€ããŠä»¥äžã®ç®æã ãã§ãããå®éã®ãšããlock_timeoutã®ç§æ°ã§timerã®èšå®å€ãå€ãããæå€§500msã®ã¿ã€ããŒã«ãªã£ãŠããããšãããããŸãã
if (c->wait_time == 0) { c->wait_time = now + c->lock_timeout; c->wait_event.handler = ngx_http_file_cache_lock_wait_handler; c->wait_event.data = r; c->wait_event.log = r->connection->log; } timer = c->wait_time - now;
ãã®lock_timeoutã¯proxy_cache_lock_timeout
ã®å€ãåç
§ããŠããããã©ã«ãã§ã¯5ç§ã«ãªã£ãŠããŸãã
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_lock_timeout
ãã£ãŠãproxy_cache_lock_timeout
ãããã©ã«ãã®ãŸãŸproxy_cache_lock
ãæå¹ã«ãããšããªã¯ãšã¹ãã¯500msããšã«ããã¯ã®ç¶æ
ã確èªããŠã¬ã¹ãã³ã¹ãè¿ãããã«ãªã£ãŠããããšãããããŸãããupstreamããããããçãæéã§å¿çãè¿ãããšããŠããã®æéã§åŸéãããŠããŸããããæå€§ã§500msã®ã¬ã€ãã³ã·ãçºçããããšãããããŸããã
察ç
察çãšèšããã»ã©ã®ãã®ã§ã¯ãããŸããããupstreamã®ã¬ã€ãã³ã·ã500msãããå°ããããšãåãã£ãŠãããšã proxy_cache_lock_timeout
ã500msãããå°ããå€ã«ããããšã§ãæå€§ã®ã¬ã€ãã³ã·ãäžããããšãã§ããŸããã
äŸãã°400msã«ããŠã¿ãçµæã以äžã®éãã§ãã
rate | avg (ÎŒs) | min (ÎŒs) | med (ÎŒs) | max (ms) | p(90) (ms) | p(95) (ms) |
---|---|---|---|---|---|---|
100 | 8,490 | 279.88 | 2,200 | 230.38 | 22.63 | 28.75 |
500 | 3,430 | 221.32 | 1,600 | 585.7 | 4.19 | 16.96 |
1,000 | 1,720 | 192.38 | 390.72 | 400.16 | 1.9 | 2.65 |
10,000 | 635.45 | 163.52 | 262.52 | 401.94 | 0.42 | 1.4 |
lock_timeoutã400msã«èšå®ãããšã500msã§ã¯ãªã400msã®ãšããã«ã¬ã€ãã³ã·ã®å£ãçãŸããããã«ãªããŸããã
ãã ãããã¯upstreamãžéããããªã¯ãšã¹ãæ°ãšã®ãã¬ãŒããªãã®é¢ä¿ã«ãããããç¡å¶éã«çãããããšã¯ã§ããŸããããã®ã¿ã€ã ã¢ãŠãæéãè¶ ãããšãããã®ãªã¯ãšã¹ãã¯ãã®ãŸãŸupstreamã«éããçµæã¯ãã£ãã·ã¥ãããªããšproxy_cache_lock_timeoutã®ããã¥ã¡ã³ãã«ã¯èšèŒãããŠããŸãããã®ããupstreamã«æåŸ ãããé床ãããçãã¿ã€ã ã¢ãŠããèšå®ããŠããŸããšããã®æéå ã«å¿çãè¿ããªãããupstreamãžã®ãªã¯ãšã¹ãæ°ãå¢ããçµæãšããŠupstreamãžã®è² è·ãå¢ããããšã«ãªããŸãã
ãŸãšã
ã€ã³ã¿ãŒã³ã·ãããéå¬ãåŠçã§ããè€æ¬ããã«æã ãæ€èšããéçã³ã³ãã³ãé ä¿¡ã·ã¹ãã ã®PoCã®è² è·æ€èšŒãè¡ã£ãŠããã ããŸãããã¡ã³ã¿ãŒãæ³å®ããŠããªãã£ããšããã«ããã©ãŒãã³ã¹äžã®åé¡ãååšããããã«ãããnginxã®ä»æ§ã§ããããšãæããã«ããŠããã ããŸããã倧å€å©ãããŸãããããããšãããããŸããã
ä»åŸã¯ãã®ãããªåé¡ãçºçããããšã念é ã«ãã©ã®ããã«éçã³ã³ãã³ãé ä¿¡ã·ã¹ãã ãæ§ç¯ãããã¡ã³ã¿ãŒã¯é ãæ±ããŠããŸãããã®ãããªåé¡ã®è§£æ±ºã«äžç·ã«åãçµãã§ããã ãã仲éãåéããŠããŸãããèå³ãããã°æ¯éãµã€ããŠãºã®æ¡çšæ å ±ãã芧ãã ããã
*1:ããã¯nginxã®ãã°ã®ç²ŸåºŠãããªç§ãŸã§ã§ããããã€ã¯ãç§ã§è¿ã£ãŠããå¿çã¯ãã°äžã§ã¯0ã«ãªã£ãŠããŸãããã§ãã衚ã®ããŒã¿ã¯ã¯ã©ã€ã¢ã³ãïŒã€ãŸãk6ïŒã®åºåããããŒã¿ãå ã«ããå€ã®ãããã€ã¯ãç§ãŸã§åºåãããŠããŸãã