ãã®èšäºã«ã¯Javaã®äŸããããŸãã Javaã§ããã°ã©ãã³ã°ããŠããªãå Žåã¯ã倧äžå€«ã§ããã¢ãããŒãèªäœãšåºæ¬ååãç解ããŠãã ããã Apache Igniteã¯ããŒã¿ããŒã¹ãšããŠäœ¿çšãããŸãããä»ã®DBMSã«ãåãã¢ãããŒããé©çšãããŸãã ãã¹ãŠã®äŸã¯ãç§ã®GitHubããããŠã³ããŒãã§ããŸãã
ãªãããããã¹ãŠå¿ èŠãªã®ã§ããïŒ
話ããå§ããŸãããã 2005幎ãç§ã¯ã©ã³ãã©ãŒã§åããŸããã ãã®æãŸã§ã«ãRamblerãŠãŒã¶ãŒã®æ°ã¯æ¥éã«å¢å ãã2å±€ã¢ãŒããã¯ãã£ã®ããµãŒããŒ-ããŒã¿ããŒã¹-ãµãŒããŒ-ã¢ããªã±ãŒã·ã§ã³ãã¯å¯ŸåŠããªããªããŸããã ããã©ãŒãã³ã¹ã®åé¡ã解決ããæ¹æ³ã«ã€ããŠèããmemcachedãã¯ãããžãŒã«æ³šç®ããŸããã
memcachedãšã¯äœã§ããïŒ Memcached-ããŒã«ãã£ãŠä¿åããããªããžã§ã¯ãã«ã¢ã¯ã»ã¹ã§ããã©ã³ãã ã¢ã¯ã»ã¹ã¡ã¢ãªå ã®ããã·ã¥ããŒãã«ã ããšãã°ããŠãŒã¶ãŒãããã¡ã€ã«ãååŸããå¿ èŠããããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯memcachedïŒ2ïŒã«ã¢ã¯ã»ã¹ããŸãã ãªããžã§ã¯ããå«ãŸããŠããå Žåã¯ãããã«ãŠãŒã¶ãŒã«è¿ãããŸãã ãªããžã§ã¯ãããªãå ŽåãããŒã¿ããŒã¹ã«ã¢ããŒã«ãè¡ããïŒ3ïŒããªããžã§ã¯ãã圢æãããŠmemcachedã«é 眮ãããŸãïŒ4ïŒã 次ã«ã次ã®åŒã³åºãã§ãããŒã¿ããŒã¹ã«å¯ŸããŠãªãœãŒã¹ãæ¶è²»ããåŒã³åºããè¡ãå¿ èŠããªããªããŸãããRAMããæ¢è£œã®ãªããžã§ã¯ãmemcachedãååŸããŸãã
memcachedã«ãããããŒã¿ããŒã¹ãèããã¢ã³ããŒããããã¢ããªã±ãŒã·ã§ã³ã®åäœãã¯ããã«éããªããŸããã ããããçµå±ã®ãšãããåã¶ã«ã¯æ©ãããŸããã çç£æ§ã®åäžãšãšãã«ãæ°ããåé¡ãçºçããŸããã
ããŒã¿ãå€æŽããå¿ èŠãããå Žåãã¢ããªã±ãŒã·ã§ã³ã¯æåã«ããŒã¿ããŒã¹ãä¿®æ£ãïŒ2ïŒãæ°ãããªããžã§ã¯ããäœæããŠããmemcachedã«é 眮ããããšããŸãïŒ3ïŒã ã€ãŸããå€ããªããžã§ã¯ããæ°ãããªããžã§ã¯ãã«çœ®ãæããå¿ èŠããããŸãã ãã®ç¬éã«æãããããšãèµ·ãããšæ³åããŠãã ãã-ã¢ããªã±ãŒã·ã§ã³ãšmemcachedéã®æ¥ç¶ãåæãããmemcachedãµãŒããŒãŸãã¯ã¢ããªã±ãŒã·ã§ã³èªäœãã¯ã©ãã·ã¥ããŸãã ãã®ãããã¢ããªã±ãŒã·ã§ã³ã¯memcachedã®ããŒã¿ãæŽæ°ã§ããŸããã§ããã ãã®çµæããŠãŒã¶ãŒã¯ãµã€ãã®ããŒãžïŒããšãã°ãèªåã®ãããã¡ã€ã«ïŒã«ç§»åããå€ãããŒã¿ã確èªããŸããããããçºçããçç±ã¯ããããŸããã
ãã®ãã°ã¯æ©èœãã¹ããŸãã¯ããã©ãŒãã³ã¹ãã¹ãäžã«æ€åºã§ããŸããïŒ ãããããç§ãã¡ã¯åœŒãèŠã€ããããªãã£ããšæãã ãã®ãããªãã°ãæ€çŽ¢ããããã«ãç¹å¥ãªã¿ã€ãã®ãã¹ã-é害æ¿å ¥ããããŸãã
éåžžããã©ãŒã«ãã€ã³ãžã§ã¯ã·ã§ã³ãã¹ãäžã«ãäžè¬ã«ãããŒãã£ã³ã°ãšåŒã°ãããã°ããããŸãã è² è·ãããã£ãŠããå Žåãã·ã¹ãã ã§è€æ°ã®ãŠãŒã¶ãŒãäœæ¥ããŠããå Žåãç°åžžãªç¶æ³ïŒæ©åšã®æ éãé»æ°ã®é®æããããã¯ãŒã¯ã®æ éãªã©ïŒãçºçããå Žåã«è¡šç€ºãããŸãã
æ°ããSberbank ITã·ã¹ãã
æ°å¹ŽåãSberbankã¯æ°ããITã·ã¹ãã ã®æ§ç¯ãéå§ããŸããã ãªãã§ïŒ äžå€®éè¡ã®ãŠã§ããµã€ãããã®çµ±èšã¯æ¬¡ã®ãšããã§ãã
åã®ç·è²ã®éšåã¯ATMã§ã®çŸéåŒãåºãã®æ°ã§ãããéè²ã®éšåã¯ååããã³ãµãŒãã¹ã«å¯ŸããŠæ¯æããªãã¬ãŒã·ã§ã³ã®æ°ã§ãã ãã£ãã·ã¥ã¬ã¹ååŒã®æ°ã¯å¹Žã å¢å ããŠããããšãããããŸãã æ°å¹ŽåŸã«ã¯ãå¢å€§ããã¯ãŒã¯ããŒãã«å¯ŸåŠããæ°ãããµãŒãã¹ãã客æ§ã«æäŸãç¶ããå¿ èŠããããŸãã ããã¯ãæ°ããSberbank ITã·ã¹ãã ãäœæããçç±ã®1ã€ã§ãã ããã«ã欧米ã®ãã¯ãããžãŒãšæ°çŸäžãã«ã®é«äŸ¡ãªã¡ã€ã³ãã¬ãŒã ãžã®äŸåãæžããããªãŒãã³ãœãŒã¹ãã¯ãããžãŒãšããŒãšã³ããµãŒããŒã«åãæ¿ããããšèããŠããŸãã
æåã«ãæ°ããSberbankã¢ãŒããã¯ãã£ã®äžå¿ã«Apache Igniteãã¯ãããžãŒã®åºç€ãæ§ç¯ããŸããã ããæ£ç¢ºã«ã¯ãææã®Gridgainãã©ã°ã€ã³ã䜿çšããŸãã ãã®ãã¯ãããžãŒã«ã¯ããªãè±å¯ãªæ©èœããããŸãããªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ïŒSQLã¯ãšãªã®ãµããŒãããããŸãïŒãNoSQLãåæ£åŠçãRAMå ã®ããŒã¿ã®ã¹ãã¬ãŒãžã®ããããã£ãçµã¿åãããŠããŸãã ããã«ãåèµ·åããŠããRAMã«ãã£ãããŒã¿ã¯ã©ãã«ã倱ãããŸããã ããŒãžã§ã³2.1以éãApache Igniteã¯ãSQLããµããŒãããApache Ignite Persistent Data Storeåæ£ãã£ã¹ã¯ã¹ãã¬ãŒãžãå°å ¥ããŸããã
ãã®ãã¯ãããžãŒã®ããã€ãã®æ©èœããªã¹ãããŸãã
- RAMã§ã®ã¹ãã¬ãŒãžãšããŒã¿åŠç
- ãã£ã¹ã¯ã¹ãã¬ãŒãž
- SQLãµããŒã
- åæ£ã¿ã¹ã¯ã®å®è¡
- æ°Žå¹³ã¹ã±ãŒãªã³ã°
ãã®æè¡ã¯æ¯èŒçæ°ãããããç¹å¥ãªæ³šæãå¿ èŠã§ãã
Sberbankã®æ°ããITã·ã¹ãã ã¯ãç©ççã«åäžã®ã¯ã©ãŠãã¯ã©ã¹ã¿ãŒã«çµã¿èŸŒãŸããæ¯èŒçå°ããªãµãŒããŒã§æ§æãããŠããŸãã ãã¹ãŠã®ããŒãã¯ãã¢ããŒãã¢ã®æ§é ã§åäžã§ãããããŒã¿ãä¿åããã³åŠçããæ©èœãå®è¡ããŸãã
ã¯ã©ã¹ã¿ãŒå ã¯ãããããã»ã«ã«åå²ãããŸãã 1ã€ã®ã»ã«ã¯8ããŒãã§ãã åããŒã¿ã»ã³ã¿ãŒã«ã¯4ã€ã®ããŒãããããŸãã
ã€ã³ã¡ã¢ãªããŒã¿ã°ãªããã§ããApache Igniteã䜿çšããŠããããããããã¯ãã¹ãŠãµãŒããŒã«åæ£ããããã£ãã·ã¥ã«ä¿åãããŸãã ããã«ããã£ãã·ã¥ã¯åãããŒãã£ã·ã§ã³ã«åå²ãããŸãã ãµãŒããŒã§ã¯ããã¡ã€ã«ãšããŠè¡šãããŸãã åããã£ãã·ã¥ã®ããŒãã£ã·ã§ã³ãç°ãªããµãŒããŒã«ä¿åã§ããŸãã ã¯ã©ã¹ã¿ãŒå ã®åããŒãã£ã·ã§ã³ã«ã¯ããã©ã€ããªããŒããšããã¯ã¢ããããŒãããããŸãã
ã¡ã€ã³ããŒãã¯ã¡ã€ã³ããŒãã£ã·ã§ã³ãæ ŒçŽãããããã«å¯ŸããèŠæ±ãåŠçããããã¯ã¢ããããŒãã£ã·ã§ã³ãæ ŒçŽãããŠããããã¯ã¢ããããŒãïŒããã¯ã¢ããããŒãïŒã«ããŒã¿ãè€è£œããŸãã
Sberbankã®æ°ããã¢ãŒããã¯ãã£ãèšèšããéã«ãã·ã¹ãã ã³ã³ããŒãã³ããæ éããå¯èœæ§ããããšããçµè«ã«éããŸããã ããšãã°ã1000å°ã®é補ããŒãšã³ããµãŒããŒã®ã¯ã©ã¹ã¿ãŒãããå ŽåãããŒããŠã§ã¢é害ãçºçããããšããããŸãã RAMã¹ããªããããããã¯ãŒã¯ã«ãŒããããŒããã©ã€ããªã©ã¯å€±æããŸãã ãã®åäœã¯ãå®å šã«éåžžã®ã·ã¹ãã åäœã§ãããšèããŸãã ãã®ãããªç¶æ³ã¯æ£ããåŠçãããå¿ èŠããããã客æ§ã¯ãããã«æ°ä»ããªãããã«ããŠãã ããã
ãã ããã·ã¹ãã ã®é害ã«å¯Ÿããèæ§ãèšèšããã ãã§ã¯äžååã§ããããããã®é害äžã«ã·ã¹ãã ããã¹ãããããšãäžå¯æ¬ ã§ãã æåãªåæ£ã·ã¹ãã ã®ç 究è ã§ããCaitie McCaffreyã®Microsoft Researchãèšãããã«ããé害ãåçŸããããŸã§ãç·æ¥ã®é害æã«ã·ã¹ãã ãã©ã®ããã«åäœãããã¯æ±ºããŠããããŸãããã
倱ãããæŽæ°
ç°¡åãªäŸãèŠãŠã¿ãŸããããééãã·ãã¥ã¬ãŒãããéè¡æ¥åã¢ããªã±ãŒã·ã§ã³ã§ãã ã¢ããªã±ãŒã·ã§ã³ã¯ãApache IgniteãµãŒããŒãšApache Igniteã¯ã©ã€ã¢ã³ãã®2ã€ã®éšåã§æ§æãããŸãã ãµãŒããŒåŽã¯ããŒã¿ãŠã§ã¢ããŠã¹ã§ãã
ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯Apache IgniteãµãŒããŒã«æ¥ç¶ããŸãã ããŒãã¢ã«ãŠã³ãIDã§å€ãã¢ã«ãŠã³ããªããžã§ã¯ãã§ãããã£ãã·ã¥ãäœæããŸãã åèšã§ã10åã®ãã®ãããªãªããžã§ã¯ãããã£ãã·ã¥ã«ä¿åãããŸãã ãã®å Žåãæåã«åã¢ã«ãŠã³ãã«$ 100ãå ¥ããŸãïŒè»¢éãããã®ãããããã«ïŒã ãããã£ãŠããã¹ãŠã®ã¢ã«ãŠã³ãã®åèšæ®é«ã¯1,000ãã«ã«ãªããŸãã
CacheConfiguration<Integer, Account> cfg = new CacheConfiguration<>(CACHE_NAME); cfg.setAtomicityMode(CacheAtomicityMode.ATOMIC); try (IgniteCache<Integer, Account> cache = ignite.getOrCreateCache(cfg)) { for (int i = 1; i <= ENTRIES_COUNT; i++) cache.put(i, new Account(i, 100)); System.out.println("Accounts before transfers"); printAccounts(cache); printTotalBalance(cache); for (int i = 1; i <= 100; i++) { int pairOfAccounts[] = getPairOfRandomAccounts(); transferMoney(cache, pairOfAccounts[0], pairOfAccounts[1]); } } ... private static void transferMoney(IgniteCache<Integer, Account> cache, int fromAccountId, int toAccountId) { Account fromAccount = cache.get(fromAccountId); Account toAccount = cache.get(toAccountId); int amount = getRandomAmount(fromAccount.balance); if (amount < 1) { return; } fromAccount.withdraw(amount); toAccount.deposit(amount); cache.put(fromAccountId, fromAccount); cache.put(toAccountId, toAccount); }
次ã«ãããã10åã®ã¢ã«ãŠã³ãéã§100åã®ã©ã³ãã ãªééãè¡ããŸãã ããšãã°ãã¢ã«ãŠã³ãAããå¥ã®ã¢ã«ãŠã³ãBã«50ãã«ãæ¯ã蟌ãŸããŸãã æŠç¥çã«ããã®ããã»ã¹ã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãã
ã·ã¹ãã ãéãããã転éã¯å éšã§ã®ã¿è¡ãããŸãã åèšæ®é«ã¯1000ãã«ã®ãŸãŸã§ãã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã
åèšæ®é«ã®æåŸ å€-$ 1000ã ããã§ã¯ãã¢ããªã±ãŒã·ã§ã³ãå°ãè€éã«ããŠã¿ãŸãããããã«ãã¿ã¹ã¯ã«ããŸãããã å®éã«ã¯ãè€æ°ã®ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ãåãã¢ã«ãŠã³ãã§åæã«åäœã§ããŸãã 10åã®ã¢ã«ãŠã³ãéã§åæã«ééãè¡ã2ã€ã®ã¿ã¹ã¯ãå®è¡ããŸãã
CacheConfiguration<Integer, Account> cfg = new CacheConfiguration<>(CACHE_NAME); cfg.setAtomicityMode(CacheAtomicityMode.ATOMIC); cfg.setCacheMode(CacheMode.PARTITIONED); cfg.setIndexedTypes(Integer.class, Account.class); try (IgniteCache<Integer, Account> cache = ignite.getOrCreateCache(cfg)) { // Initializing the cache. for (int i = 1; i <= ENTRIES_COUNT; i++) cache.put(i, new Account(i, 100)); System.out.println("Accounts before transfers"); System.out.println(); printAccounts(cache); printTotalBalance(cache); IgniteRunnable run1 = new MyIgniteRunnable(cache, ignite,1); IgniteRunnable run2 = new MyIgniteRunnable(cache, ignite,2); List<IgniteRunnable> arr = Arrays.asList(run1, run2); ignite.compute().run(arr); } ... private void transferMoney(int fromAccountId, int toAccountId) { Account fromAccount = cache.get(fromAccountId); Account toAccount = cache.get(toAccountId); int amount = getRandomAmount(fromAccount.balance); if (amount < 1) { return; } int fromAccountBalanceBeforeTransfer = fromAccount.balance; int toAccountBalanceBeforeTransfer = toAccount.balance; fromAccount.withdraw(amount); toAccount.deposit(amount); cache.put(fromAccountId, fromAccount); cache.put(toAccountId, toAccount); }
åèšæ®é«ã¯1296ãã«ã§ãã 顧客ã¯åã¶ãéè¡ã¯æ倱ã被ãã ãªããããèµ·ãã£ãã®ã§ããïŒ
ããã§ã¯ã2ã€ã®ã¿ã¹ã¯ãåæã«ã¢ã«ãŠã³ãAã®ç¶æ ãã©ã®ããã«å€æŽãããã確èªããŸãããããã2çªç®ã®ã¿ã¹ã¯ã¯æåã®ã¿ã¹ã¯ãããæ©ããã®å€æŽãèšé²ããŸãã ãã®åŸãæåã®ã¿ã¹ã¯ã¯ãã®å€æŽãèšé²ãã2çªç®ã®ã¿ã¹ã¯ã«ãã£ãŠè¡ããããã¹ãŠã®å€æŽã¯ããã«æ¶ããŸãã ãã®ç°åžžã¯ãæŽæ°ã®æ倱ã®åé¡ãšåŒã°ããŸãã
ã¢ããªã±ãŒã·ã§ã³ãæ£åžžã«æ©èœããããã«ã¯ãããŒã¿ããŒã¹ãACIDãã©ã³ã¶ã¯ã·ã§ã³ããµããŒãããã³ãŒãããããèæ ®ããå¿ èŠããããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®ACIDããããã£ãèŠãŠããããéåžžã«éèŠã§ããçç±ãç解ããŸãããã
- A-ååæ§ãååæ§ã ææ¡ããããã¹ãŠã®å€æŽãããŒã¿ããŒã¹ã«å¯ŸããŠè¡ãããããäœãè¡ãããŸããã ã€ãŸããã¹ããã3ãš6ã®éã«é害ãçºçããå Žåãå€æŽã¯ããŒã¿ããŒã¹ã«ããã¹ãã§ã¯ãããŸããã
- C-äžè²«æ§ãæŽåæ§ã ãã©ã³ã¶ã¯ã·ã§ã³ãå®äºããåŸãããŒã¿ããŒã¹ã¯äžè²«ããç¶æ
ãç¶æããå¿
èŠããããŸãã ãã®äŸã§ã¯ãããã¯AãšBã®åèšãåžžã«åãã§ãããåèšæ®é«ã1000ãã«ã§ããããšãæå³ããŸãã
- I-åé¢ãåé¢ã ãã©ã³ã¶ã¯ã·ã§ã³ãçžäºã«åœ±é¿ããããšã¯ãããŸããã äžæ¹ã®ãã©ã³ã¶ã¯ã·ã§ã³ãæ¯æ¿ãè¡ããããäžæ¹ãã¹ããã3ããã¹ããã6ãŸã§ã®ã¢ã«ãŠã³ãAãšBã®å€ãåãåã£ãå Žåã圌女ã¯ã·ã¹ãã ã«å¿
èŠä»¥äžã®ãéããªããšèããŸãã ããã«åŸ®åŠãªéãããããŸãããåŸã§è©³ãã説æããŸãã
- D-èä¹
æ§ ãã©ã³ã¶ã¯ã·ã§ã³ãããŒã¿ããŒã¹ãžã®å€æŽãã³ãããããåŸããããã®å€æŽã¯å€±æã®çµæãšããŠå€±ãããã¹ãã§ã¯ãããŸããã
ãããã£ãŠãtransferMoneyã¡ãœããã§ã¯ããã©ã³ã¶ã¯ã·ã§ã³å ã§ééãè¡ããŸãã
private void transferMoney(int fromAccountId, int toAccountId) { try (Transaction tx = ignite.transactions().txStart()) { Account fromAccount = cache.get(fromAccountId); Account toAccount = cache.get(toAccountId); int amount = getRandomAmount(fromAccount.balance); if (amount < 1) { return; } int fromAccountBalanceBeforeTransfer = fromAccount.balance; int toAccountBalanceBeforeTransfer = toAccount.balance; fromAccount.withdraw(amount); toAccount.deposit(amount); cache.put(fromAccountId, fromAccount); cache.put(toAccountId, toAccount); tx.commit(); } catch (Exception e){ e.printStackTrace(); } }
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã
ãã ãã©ã³ã¶ã¯ã·ã§ã³ã¯åœ¹ã«ç«ã¡ãŸããã§ããã åèšæ®é«ã¯6951ãã«ã§ãïŒ ãã®ã¢ããªã±ãŒã·ã§ã³ã®åäœã®åé¡ã¯äœã§ããïŒ
ãŸããATOMICãã£ãã·ã¥ã¿ã€ããéžæããŸããã ACIDãã©ã³ã¶ã¯ã·ã§ã³ãµããŒããªãïŒ
CacheConfiguration<Integer, Account> cfg = new CacheConfiguration<>(CACHE_NAME); cfg.setAtomicityMode(CacheAtomicityMode.TOMIC);
次ã«ãtxStartã¡ãœããã«ã¯ãenumåã®2ã€ã®éèŠãªãã©ã¡ãŒã¿ãŒãæå®ã§ããŸããããã¯ãããã¯ã¡ãœããïŒApache Igniteã®åæå®è¡ã¢ãŒãïŒãšåé¢ã¬ãã«ã§ãã ãããã®ãã©ã¡ãŒã¿ã®å€ã«å¿ããŠããã©ã³ã¶ã¯ã·ã§ã³ã¯ããŸããŸãªæ¹æ³ã§ããŒã¿ãèªã¿æžãã§ããŸãã Apache Igniteã§ã¯ããããã®ãã©ã¡ãŒã¿ãŒã¯æ¬¡ã®ããã«èšå®ãããŸãã
try (Transaction tx = ignite.transactions().txStart( , )) { Account fromAccount = cache.get(fromAccountId); Account toAccount = cache.get(toAccountId); ... tx.commit(); }
LOCK METHODãã©ã¡ãŒã¿ãŒã®å€ãšããŠãPESSIMISTICïŒæ²èŠ³çããã¯ïŒãŸãã¯OPTIMISTICïŒæ¥œèŠ³çããã¯ïŒã䜿çšã§ããŸãã ãããã¯ã®ç¬éãç°ãªããŸãã PESSIMISTICã䜿çšããå Žåãæåã®èªã¿åã/æžã蟌ã¿æã«ããã¯ã課ããããã©ã³ã¶ã¯ã·ã§ã³ãã³ãããããããŸã§ä¿æãããŸãã ããšãã°ãæ²èŠ³çããã¯ãã©ã³ã¶ã¯ã·ã§ã³ãã¢ã«ãŠã³ãAããã¢ã«ãŠã³ãBãžã®è»¢éãè¡ãå Žåã転éãè¡ããã©ã³ã¶ã¯ã·ã§ã³ãã³ãããããããŸã§ãä»ã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯ãããã®ã¢ã«ãŠã³ãã®å€ãèªã¿æžãã§ããŸããã ä»ã®ãã©ã³ã¶ã¯ã·ã§ã³ãã¢ã«ãŠã³ãAãšBã«ã¢ã¯ã»ã¹ãããå Žåããã©ã³ã¶ã¯ã·ã§ã³ã®å®äºãåŸ ããªããã°ãªããªãããšã¯æããã§ããããã¯ãã¢ããªã±ãŒã·ã§ã³ã®å šäœçãªããã©ãŒãã³ã¹ã«æªåœ±é¿ãåãŒããŸãã 楜芳çããã¯ã¯ä»ã®ãã©ã³ã¶ã¯ã·ã§ã³ã®ããŒã¿ãžã®ã¢ã¯ã»ã¹ãå¶éããŸããããã³ãããã®ãã©ã³ã¶ã¯ã·ã§ã³ã®æºåãã§ãŒãºïŒæºåãã§ãŒãºãApache Igniteã¯2PCãããã³ã«ã䜿çšïŒã§ããã§ãã¯ãå®è¡ãããŸã-ä»ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§ããŒã¿ãå€æŽãããŸãããïŒ ãŸããå€æŽãè¡ãããå Žåããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã£ã³ã»ã«ãããŸãã ããã©ãŒãã³ã¹ã®èŠ³ç¹ã§ã¯ãOPTIMISTICã¯ããé«éã«å®è¡ãããŸãããããŒã¿ã䜿çšãã競åäœæ¥ããªãã¢ããªã±ãŒã·ã§ã³ã«ããé©ããŠããŸãã
INSULATION LEVELãã©ã¡ãŒã¿ãŒã¯ããã©ã³ã¶ã¯ã·ã§ã³ã®çžäºåé¢ã®çšåºŠã決å®ããŸãã SQL ANSI / ISOæšæºã§ã¯4çš®é¡ã®åé¢ãå®çŸ©ãããŠãããååé¢ã¬ãã«ã§åããã©ã³ã¶ã¯ã·ã§ã³ã·ããªãªãç°ãªãçµæãããããå¯èœæ§ããããŸãã
- READ_UNCOMMITEDã¯æãäœãåé¢ã¬ãã«ã§ãã ãã©ã³ã¶ã¯ã·ã§ã³ã¯ããããŒãã£ãªãã³ããããããŠããªãããŒã¿ãèŠãããšãã§ããŸãã
- READ_COMMITTED-ãã©ã³ã¶ã¯ã·ã§ã³ãå
éšã§æ©å¯ããŒã¿ã®ã¿ãèŠãå Žå
- REPEATABLE_READ-ãã©ã³ã¶ã¯ã·ã§ã³å
ã§èªã¿åããè¡ãããå Žåããã®èªã¿åãã¯ç¹°ãè¿ãå¯èœã§ãªããã°ãªããªãããšãæå³ããŸãã
- SERIALIZABLE-ãã®ã¬ãã«ã¯ãã·ã¹ãã ã«ä»ã®ãŠãŒã¶ãŒãããªããã®ããã«ãæ倧ââéã®ãã©ã³ã¶ã¯ã·ã§ã³åé¢ãæ³å®ããŠããŸãã 䞊åãã©ã³ã¶ã¯ã·ã§ã³ã®çµæã¯ãããããé çªã«å®è¡ããããã®ããã«ãªããŸãã ããããé«åºŠãªåé¢ãšãšãã«ãããã©ãŒãã³ã¹ãäœäžããŸãã ãããã£ãŠããã®ã¬ãã«ã®åé¢ãæ
éã«éžæããå¿
èŠããããŸãã
å€ãã®ææ°ã®DBMSïŒMicrosoft SQL ServerãPostgreSQLãããã³OracleïŒã®å Žåãããã©ã«ãã®åé¢ã¬ãã«ã¯READ_COMMITTEDã§ãã ãã®äŸã§ã¯ã倱ãããæŽæ°ããä¿è·ãããªããããããã¯èŽåœçã§ãã çµæã¯ããã©ã³ã¶ã¯ã·ã§ã³ããŸã£ãã䜿çšããªãã£ãå Žåãšåãã«ãªããŸãã
Apache Igniteãã©ã³ã¶ã¯ã·ã§ã³ããã¥ã¡ã³ããããããã¯ã¡ãœãããšåé¢ã¬ãã«ã®çµã¿åããã䜿çšããããšãé©åã§ãã
- PESSIMISTIC REPEATABLE_READ-ããŒã¿ã®æåã®èªã¿åããŸãã¯æžã蟌ã¿æã«ããã¯ã課ãããå®äºãããŸã§ä¿æãããŸãã
- PESSIMISTIC SERIALIZABLE -PESSIMISTIC REPEATABLE_READãšåæ§ã«æ©èœããŸã
- OPTIMISTIC SERIALIZABLE-æåã®èªã¿åãåŸã«ååŸãããããŒã¿ã®ããŒãžã§ã³ãèšæ¶ãããã³ãããã®æºå段éã§ãã®ããŒãžã§ã³ãç°ãªãå ŽåïŒããŒã¿ãå¥ã®ãã©ã³ã¶ã¯ã·ã§ã³ã«ãã£ãŠå€æŽãããå ŽåïŒããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã£ã³ã»ã«ãããŸãã ãã®ãªãã·ã§ã³ãè©ŠããŠã¿ãŸãããã
private void transferMoney(int fromAccountId, int toAccountId) { try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) { Account fromAccount = cache.get(fromAccountId); Account toAccount = cache.get(toAccountId); int amount = getRandomAmount(fromAccount.balance); if (amount < 1) { return; } int fromAccountBalanceBeforeTransfer = fromAccount.balance; int toAccountBalanceBeforeTransfer = toAccount.balance; fromAccount.withdraw(amount); toAccount.deposit(amount); cache.put(fromAccountId, fromAccount); cache.put(toAccountId, toAccount); tx.commit(); } catch (Exception e){ e.printStackTrace(); } }
Hoorayãäºæ³éã1,000ãã«ãåŸãŸããã 3åç®ã®è©Šè¡ã
è² è·äžã§ã®ãã¹ã
ããã§ããã¹ããããçŸå®çã«ããŸã-è² è·ã®äžã§ãã¹ãããŸãã ããã«ããµãŒããŒããŒããè¿œå ããŸãã ã¹ãã¬ã¹ãã¹ããå®æœããããã®ããŒã«ã¯å€æ°ãããŸãããSberbankã§ã¯HP Performance Centerã䜿çšããŠããŸãã ããã¯ããªã匷åãªããŒã«ã§ããã50以äžã®ãããã³ã«ããµããŒããã倧èŠæš¡ãªããŒã åãã«èšèšãããŠãããå€å€§ãªè²»çšãããããŸãã JMeterã§ãµã³ãã«ãäœæããŸãããç¡æã§ãåé¡ã100ïŒ è§£æ±ºããŸãã Javaã§ã³ãŒããæžãçŽããããªãã®ã§ãJSR223ãµã³ãã©ãŒã䜿çšããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã¹ããJARã¢ãŒã«ã€ããäœæãããã¹ãèšç»ã«ããŒãããŸãã ãã£ãã·ã¥ãäœæããŠèšå®ããã«ã¯ãCreateCacheã¯ã©ã¹ãå®è¡ããŸãã ãã£ãã·ã¥ãåæåãããåŸãJMeterã¹ã¯ãªãããå®è¡ã§ããŸãã
ãã¹ãŠãã¯ãŒã«ã§ã1,000ãã«ãç²åŸããŸããã
ã¯ã©ã¹ã¿ãŒããŒãã®ã¯ã©ãã·ã¥
ããã§ãããç Žå£çãªãã®ã«ãªããŸããã¯ã©ã¹ã¿ãŒæäœäžã«ã2ã€ã®ãµãŒããŒããŒãã®1ã€ãã¯ã©ãã·ã¥ãããŸãã Gridgainããã±ãŒãžã«å«ãŸããŠããVisorãŠãŒãã£ãªãã£ã䜿çšããŠãApache Igniteã¯ã©ã¹ã¿ãŒãç£èŠããããŸããŸãªããŒã¿ãµã³ãã«ãäœæã§ããŸãã [SQLãã¥ãŒã¢]ã¿ãã§ãSQLã¯ãšãªãå®è¡ããŠããã¹ãŠã®ã¢ã«ãŠã³ãã®å šäœçãªæ®é«ãååŸããŸãã
ãªã«ïŒ 553ãã«ã 顧客ã¯ææã«é¥ããéè¡ã¯è©å€ã倱ããŸãã ä»åã¯äœãééããŸãããïŒ
Apache Igniteã«ã¯ãã£ãã·ã¥ã¿ã€ãããããŸãã
- ããŒãã£ã·ã§ã³å-1ã€ãŸãã¯è€æ°ã®ããã¯ã¢ããã€ã³ã¹ã¿ã³ã¹ãã¯ã©ã¹ã¿ãŒå
ã«æ ŒçŽãããŸã
- è€è£œããããã£ãã·ã¥-ãã¹ãŠã®ããŒãã£ã·ã§ã³ïŒãã£ãã·ã¥ã®ãã¹ãŠã®æçïŒã¯1ã€ã®ãµãŒããŒã«ä¿åãããŸãã ãã®ãããªãã£ãã·ã¥ã¯ãäž»ã«ãªãã¡ã¬ã³ã¹ããã¯ã«é©ããŠããŸããããã¯ãã£ãã«å€æŽããããããèªãŸããŸãã
- ããŒã«ã«-1ã€ã®ããŒãäžã®ãã¹ãŠ
ããŒã¿ãé »ç¹ã«å€æŽãããããããŒãã£ã·ã§ã³åããããã£ãã·ã¥ãéžæããè¿œå ã®ããã¯ã¢ãããè¿œå ããŸãã ã€ãŸããããŒã¿ã®2ã€ã®ã³ããŒïŒãã©ã€ããªãšããã¯ã¢ããïŒããããŸãã
CacheConfiguration<Integer, Account> cfg = new CacheConfiguration<>(CACHE_NAME); cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); cfg.setCacheMode(CacheMode.PARTITIONED); cfg.setBackups(1);
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã ééåã«1000ãã«ãæã£ãŠããããšãæãåºããŠãã ããã éå§ããæäœäžã«ããŒãã®1ã€ããæ¶ãã
VisorãŠãŒãã£ãªãã£ã§ã¯ãSQLã¯ãšãªãäœæããŠåèšæ®é«1000ãã«ãååŸããŸãã ãã¹ãŠãããŸããããŸããïŒ
ä¿¡é Œæ§ã®äºäŸ
2幎åãæ°ããSberbank ITã·ã¹ãã ã®ãã¹ããéå§ããŸããã ã©ããããããç§ãã¡ã¯ãšã¹ã³ãŒããšã³ãžãã¢ã«è¡ãããäœãå£ããã®ãããšå°ããŸããã 圌ãã¯ç§ãã¡ã«çããïŒãã¹ãŠãå£ããå¯èœæ§ãããããã¹ãŠããã¹ãããïŒ ãã¡ããããã®çãã¯ç§ãã¡ã«åããªãã£ãã ç§ãã¡ã¯äžç·ã«åº§ã£ãŠãé害統èšãåæããçºçããå¯èœæ§ãæãé«ãã±ãŒã¹ãããŒãé害ã§ããããšãèªèããŸããã
ããã«ãããã¯ãŸã£ããç°ãªãçç±ã§çºçããå¯èœæ§ããããŸãã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ãã·ã¥ããããJVMãã¯ã©ãã·ã¥ããããOSãã¯ã©ãã·ã¥ããããããŒããŠã§ã¢ã«é害ãçºçãããããŸãã
èãããããã¹ãŠã®é害äºäŸã4ã€ã®ã°ã«ãŒãã«åããŸããã
- è£
åå
- ãããã¯ãŒã¯
- ãœãããŠã§ã¢
- ãã®ä»
圌ãã¯åœŒãã®ããã«ãã¹ããèãåºããä¿¡é Œæ§ã®ã±ãŒã¹ãšåŒãã ã äžè¬çãªä¿¡é Œæ§ã®ã±ãŒã¹ã¯ããã¹ãåã®ã·ã¹ãã ã®ç¶æ ã®èª¬æãé害ãåçŸããæé ãããã³é害äžã®äºæ³ãããåäœã®èª¬æã§æ§æãããŸãã
ä¿¡é Œæ§ã®ã±ãŒã¹ïŒæ©åš
ãã®ã°ã«ãŒãã«ã¯ã次ã®ãããªã±ãŒã¹ãå«ãŸããŸãã
- åé»
- ããŒããã©ã€ããžã®ã¢ã¯ã»ã¹ãå®å
šã«å€±ããã
- 1ã€ã®ããŒããã©ã€ãã¢ã¯ã»ã¹ãã¹ã®é害
- CPUãRAMããã£ã¹ã¯ããããã¯ãŒã¯è² è·
ã¯ã©ã¹ã¿ãŒã«ã¯ãåããŒãã£ã·ã§ã³ã®4ã€ã®åäžã³ããŒïŒ1ã€ã®ãã©ã€ããªããŒãã£ã·ã§ã³ãš3ã€ã®ããã¯ã¢ããããŒãã£ã·ã§ã³ïŒãæ ŒçŽãããŸãã ããŒããŠã§ã¢é害ã®ããã«ããŒããã¯ã©ã¹ã¿ãŒãé¢ãããšããŸãã ãã®å Žåãã¡ã€ã³ããŒãã£ã·ã§ã³ã¯ä»ã®çãæ®ã£ãŠããããŒãã«ç§»åããå¿ èŠããããŸãã
ä»ã«äœãèµ·ããã§ããããïŒ ã»ã«å ã®ã©ãã¯ã®æ倱ã
ã»ã«ã®ãã¹ãŠã®ããŒãã¯ç°ãªãã©ãã¯ã«ãããŸãã ã€ãŸã ã©ãã¯åºåã¯ãã¯ã©ã¹ã¿ãŒé害ãããŒã¿æ倱ã«ã€ãªãããŸããã 4ã€ã®ã³ããŒã3ã€ãããŸãã ãã ããããŒã¿ã»ã³ã¿ãŒå šäœã倱ããããšããŠãã倧ããªåé¡ã«ã¯ãªããŸããã 4ã€ã®ããŒã¿ã®ã³ããŒããŸã 2ã€ãããŸãã
äžéšã®ã±ãŒã¹ã¯ããµããŒããšã³ãžãã¢ã®æ¯æŽãåããŠããŒã¿ã»ã³ã¿ãŒã§çŽæ¥å®è¡ãããŸãã ããšãã°ãããŒããã©ã€ãããªãã«ãããµãŒããŒãŸãã¯ã©ãã¯ã®é»æºããªãã«ããŸãã
ä¿¡é Œæ§ã®ã±ãŒã¹ïŒãããã¯ãŒã¯
ãããã¯ãŒã¯ã®æçåã«é¢é£ããã±ãŒã¹ããã¹ãããã«ã¯ãiptablesã䜿çšããŸãã ãããŠãNetEmãŠãŒãã£ãªãã£ã䜿çšããŠãšãã¥ã¬ãŒãããŸãïŒ
- ç°ãªãååžé¢æ°ã«ãããããã¯ãŒã¯é
延
- ãã±ããæ倱
- ãã±ããåè©Šè¡
- ãã±ããã®äžŠã¹æ¿ã
- ãã±ããæªã¿
ç§ãã¡ããã¹ãããŠãããã1ã€ã®èå³æ·±ããããã¯ãŒã¯ã±ãŒã¹ã¯ãã¹ããªãããã¬ã€ã³ã§ãã ããã¯ãã¯ã©ã¹ã¿ãŒã®ãã¹ãŠã®ããŒããåäœããŠãããšãã§ããããããã¯ãŒã¯ã»ã°ã¡ã³ããŒã·ã§ã³ã®ããã«ããããã¯äºãã«éä¿¡ã§ããŸããã ãã®çšèªã¯å»åŠã«ç±æ¥ããè³ã¯2ã€ã®åçã«åãããŠããããããããç¬èªã®ãã®ã§ãããšèããŠããŸãã ã¯ã©ã¹ã¿ã§ãåãããšãèµ·ãããŸãã
ããŒã¿ã»ã³ã¿ãŒéã§æ¥ç¶ã倱ãããããšããããŸãã ããšãã°ãæšå¹Žãæåæ©ã«ããå ãã¡ã€ããŒã±ãŒãã«ã®æå·ã«ãããããã«éè¡ããªãã¯ãªãã£ãŒéè¡ããã±ãããã³ã¯éè¡ã®éè¡ã®é¡§å®¢ã¯æ°æéã€ã³ã¿ãŒãããäžã§ååŒãè¡ããã端æ«ã¯ã«ãŒããåãå ¥ãããATMã¯æ©èœããŸããã§ããã ãã®äºæ ã«ã€ããŠå€ãã®ããšãTwitterã§æžãããŠããŸãã
ãã®å Žåãã¹ããªãããã¬ã€ã³ã®ç¶æ³ã¯æ£ããåŠçãããã¯ãã§ãã ã°ãªããã¯ã¹ããªãããã¬ã€ã³ãèå¥ããã¯ã©ã¹ã¿ãŒã2ã€ã®éšåã«åå²ããŸãã ååã¯èªã¿åãã¢ãŒãã«ãªããŸãã ããã¯ãããå€ãã®çããŠããããŒããããããã³ãŒãã£ããŒã¿ãŒãé 眮ãããŠããååã§ãïŒã¯ã©ã¹ã¿ãŒå ã§æãå€ãããŒãïŒã
ä¿¡é Œæ§ã®ã±ãŒã¹ïŒãœãããŠã§ã¢
ãããã¯ãããŸããŸãªãµãã·ã¹ãã ã®é害ã«é¢é£ããã±ãŒã¹ã§ãã
- DPL ORM-Hibernate ORMãªã©ã®ããŒã¿ã¢ã¯ã»ã¹ã¢ãžã¥ãŒã«
- ã¢ãžã¥ãŒã«éãã©ã³ã¹ããŒã-ã¢ãžã¥ãŒã«éã®ã¡ãã»ãŒãžã³ã°ïŒãã€ã¯ããµãŒãã¹ïŒ
- ãã®ã³ã°ã·ã¹ãã
- ã¢ã¯ã»ã¹ã·ã¹ãã
- Apache Igniteã¯ã©ã¹ã¿ãŒ
- ...
ã»ãšãã©ã®ãœãããŠã§ã¢ã¯Javaã§èšè¿°ãããŠãããããJavaã¢ããªã±ãŒã·ã§ã³ã«åºæã®ãã¹ãŠã®åé¡ãçºçãããããªããŸãã ããŸããŸãªã¬ããŒãžã³ã¬ã¯ã¿ãŒèšå®ããã¹ãããŸãã ã¯ã©ãã·ã¥Javaä»®æ³ãã·ã³ã§ãã¹ããå®è¡ããŸãã
Apache Igniteã¯ã©ã¹ã¿ãŒã®å ŽåããªãããŒãã®ç¹å¥ãªã±ãŒã¹ããããŸã-ããã¯Apache Igniteãå¶åŸ¡ããã¡ã¢ãªé åã§ãã JavaããŒããããã¯ããã«å€§ãããããŒã¿ãšã€ã³ããã¯ã¹ãæ ŒçŽããããã«èšèšãããŠããŸãã ããã§ã¯ãããšãã°ããªãŒããŒãããŒããã¹ãã§ããŸãã ãªãããŒãããªãŒããŒãããŒãããäžéšã®ããŒã¿ãRAMã«åãŸããªãå Žåã®ã¯ã©ã¹ã¿ãŒã®åäœã確èªããŸãã ãã£ã¹ã¯ããèªã¿åããŸãã
ãã®ä»ã®å Žå
ãããã¯ãæåã®3ã€ã®ã°ã«ãŒãã«å«ãŸããªãã±ãŒã¹ã§ãã ãããã«ã¯ãé倧ãªäºæ ãçºçããå ŽåããŸãã¯ããŒã¿ãå¥ã®ã¯ã©ã¹ã¿ãŒã«ç§»è¡ãããå Žåã«ããŒã¿ãå埩ã§ãããŠãŒãã£ãªãã£ãå«ãŸããŸãã
- ããŒã¿ã®ã¹ãããã·ã§ããïŒããã¯ã¢ããïŒãäœæããããã®ãŠãŒãã£ãªãã£-å®å
šããã³å¢åã¹ãããã·ã§ããã®ãã¹ãã
- ç¹å®ã®æç¹ãžã®å埩ã¯ãPITRïŒPoint in-time recoveryïŒã¡ã«ããºã ã§ãã
é害æ¿å ¥ã®ããã®ãŠãŒãã£ãªãã£
ç§ã®ã¬ããŒãã®äŸãžã®ãªã³ã¯ãæãåºãããŠãã ããã Apache Igniteãã£ã¹ããªãã¥ãŒã·ã§ã³ã¯ãå ¬åŒãµã€ãApache Apache Ignite DownloadsããããŠã³ããŒãã§ããŸãã ãããŠãããªããçªç¶ãã®ãããã¯ã«èå³ãæã€ããã«ãªã£ãå ŽåãSberbankã§äœ¿çšããŠãããŠãŒãã£ãªãã£ãå ±æããŸãã
ãã¬ãŒã ã¯ãŒã¯
æ§æ管çïŒ
LinuxãŠãŒãã£ãªãã£ïŒ
- NetEmïŒtcïŒ
- ã¹ãã¬ã¹ng
- Iperf
- ãã«-9
- iptables
è² è·ãã¹ãããŒã«ïŒ
çŸä»£äžçãšSberbankã®äž¡æ¹ã§ããã¹ãŠã®å€æŽã¯åçã§ãããä»åŸæ°å¹Žéã§ã©ã®ãã¯ãããžãŒã䜿çšãããããäºæž¬ããããšã¯å°é£ã§ãã ããããFault Injectionã¡ãœããã䜿çšããããšã¯ç¢ºãã§ãã ãã®æ¹æ³ã¯æ®éçã§ããããããæè¡ã®ãã¹ãã«é©ããŠããŸããå®éã«æ©èœããå€ãã®ãã°ããã£ããããéçºãã補åãæ¹åããã®ã«åœ¹ç«ã¡ãŸãã