जावा प्रदर्शन में उल्लेखनीय सुधार कैसे करें?


23

LMAX पर टीम के पास एक प्रस्तुति है कि वे 1k से कम ms विलंब से 100k TPS कैसे कर पाए । उन्होंने उस प्रस्तुति को एक ब्लॉग , तकनीकी पेपर (पीडीएफ) और स्वयं स्रोत कोड के साथ बैकअप दिया है।

हाल ही में, मार्टिन फाउलर ने LMAX वास्तुकला पर एक उत्कृष्ट पत्र प्रकाशित किया और उल्लेख किया कि वे अब प्रति सेकंड छह मिलियन आदेशों को संभालने में सक्षम हैं और कुछ कदमों को उजागर करते हैं जो टीम ने प्रदर्शन में परिमाण के एक और क्रम को बढ़ाने के लिए उठाए।

अब तक मैंने समझाया है कि बिजनेस लॉजिक प्रोसेसर की गति की कुंजी सब कुछ क्रमिक रूप से, इन-मेमोरी कर रही है। बस ऐसा करने से (और वास्तव में कुछ भी बेवकूफ नहीं है) डेवलपर्स को कोड लिखने की अनुमति देता है जो 10K TPS को संसाधित कर सकता है।

उन्होंने तब पाया कि अच्छे कोड के सरल तत्वों पर ध्यान केंद्रित करने से इसे 100K TPS रेंज में लाया जा सकता है। इसे बस अच्छी तरह से कोडित कोड और छोटे तरीकों की आवश्यकता है - अनिवार्य रूप से यह हॉटस्पॉट को अनुकूलन के बेहतर काम करने की अनुमति देता है और सीपीयू के लिए कोड को कैशिंग में अधिक कुशल होना चाहिए क्योंकि यह चल रहा है।

परिमाण के एक और क्रम को बढ़ाने के लिए थोड़ी अधिक चतुराई हुई। कई चीजें हैं जो LMAX टीम को वहां पहुंचने में मददगार साबित हुईं। एक जावा संग्रह के कस्टम कार्यान्वयन को लिखना था जो कचरे के साथ कैश-फ्रेंडली और सावधान रहने के लिए डिज़ाइन किए गए थे।

प्रदर्शन के शीर्ष स्तर तक पहुंचने की एक और तकनीक प्रदर्शन परीक्षण पर ध्यान दे रही है। मैंने लंबे समय से देखा है कि लोग प्रदर्शन को बेहतर बनाने के लिए तकनीकों के बारे में बहुत सारी बातें करते हैं, लेकिन एक चीज जो वास्तव में फर्क करती है वह है इसका परीक्षण करना

फाउलर ने उल्लेख किया कि कई चीजें हैं जो पाई गईं, लेकिन उन्होंने केवल एक जोड़े का उल्लेख किया।

क्या अन्य आर्किटेक्चर, लाइब्रेरी, तकनीक या "चीजें" हैं जो प्रदर्शन के ऐसे स्तरों तक पहुंचने में सहायक हैं?


11
"ऐसे अन्य आर्किटेक्चर, लाइब्रेरी, तकनीक या" चीजें "प्रदर्शन के ऐसे स्तरों तक पहुंचने में सहायक हैं?" क्यों पूछें? यही कारण है कि उद्धरण है निश्चित सूची। बहुत सारी और बहुत सी अन्य चीजें हैं, जिनमें से कोई भी उस सूची में वस्तुओं के प्रकार का प्रभाव नहीं है। किसी और को कोई भी नाम दे सकता है वह सूची के रूप में उपयोगी नहीं होगा। बुरे विचारों के लिए क्यों पूछें जब आपने सबसे अच्छी अनुकूलन सूची में से एक का उत्पादन किया है?
S.Lott

यह सीखना अच्छा होगा कि वे कौन से टूल का उपयोग करते हैं कि सिस्टम पर उत्पन्न कोड कैसे चलता है।

1
मैंने सभी प्रकार की तकनीकों के बारे में लोगों को सुना है। मैंने जो सबसे प्रभावी पाया है वह सिस्टम स्तर की रूपरेखा है। यह आपके कार्यक्रम और कार्यभार के तरीके को नियंत्रित करने के तरीकों में आपको अड़चन दिखा सकता है। मैं प्रदर्शन और मॉड्यूलर कोड लिखने के बारे में अच्छी तरह से ज्ञात दिशानिर्देशों का पालन करने का सुझाव दूंगा ताकि आप इसे बाद में आसानी से ट्यून कर सकें ... मुझे नहीं लगता कि आप सिस्टम प्रोफाइलिंग में गलत हो सकते हैं।
रितेश

जवाबों:


21

उच्च-प्रदर्शन लेन-देन प्रसंस्करण के लिए सभी प्रकार की तकनीकें हैं और फाउलर के लेख में से एक रक्तस्रावी किनारे पर कई में से एक है। तकनीकों का एक गुच्छा सूचीबद्ध करने के बजाय, जो किसी की स्थिति पर लागू हो भी सकता है और नहीं भी हो सकता है, मुझे लगता है कि बुनियादी सिद्धांतों पर चर्चा करना बेहतर है और LMAX उनमें से बड़ी संख्या को कैसे संबोधित करता है।

एक उच्च-स्तरीय लेन-देन प्रसंस्करण प्रणाली के लिए आप निम्न में से सभी को यथासंभव करना चाहते हैं:

  1. सबसे कम स्टोरेज टियर में बिताए गए समय को कम से कम करें। सबसे तेज़ से सबसे धीमी गति से आधुनिक सर्वर पर आपके पास: CPU / L1 -> L2 -> L3 -> RAM -> डिस्क / LAN -> WAN। अनुक्रमिक पहुंच के लिए सबसे तेज आधुनिक चुंबकीय डिस्क से सबसे धीमी रैम तक की छलांग 1000x से अधिक है ; रैंडम एक्सेस और भी बदतर है।

  2. प्रतीक्षा में बिताए समय को कम या कम करना । इसका मतलब है कि जितना संभव हो उतना कम राज्य साझा करना और, जब भी राज्य साझा किया जाना चाहिए, जब भी संभव हो स्पष्ट ताले से बचें।

  3. काम का बोझ फैलाएं। सीपीयू बहुत तेजी से पिछले कई वर्षों में मिल गया है नहीं है, लेकिन वे है छोटे मिल गया, और 8 कोर एक सर्वर पर बहुत आम है। इसके अलावा, आप कई मशीनों पर काम भी फैला सकते हैं, जो कि Google का दृष्टिकोण है; इसके बारे में महान बात यह है कि यह I / O सहित सभी चीजों को मापता है ।

फाउलर के अनुसार, LMAX इनमें से प्रत्येक के लिए निम्नलिखित दृष्टिकोण अपनाता है:

  1. हर समय सभी स्थिति को स्मृति में रखें । अधिकांश डेटाबेस इंजन वास्तव में वैसे भी ऐसा करेंगे, यदि पूरा डेटाबेस मेमोरी में फिट हो सकता है, लेकिन वे मौका देने के लिए कुछ भी नहीं छोड़ना चाहते हैं, जो वास्तविक समय के ट्रेडिंग प्लेटफॉर्म पर समझ में आता है। जोखिम के एक टन को जोड़े बिना इसे खींचने के लिए, उन्हें हल्के बैकअप और विफलता के बुनियादी ढांचे का एक गुच्छा बनाना पड़ा।

  2. इनपुट घटनाओं की धारा के लिए एक लॉक-फ्री कतार ("व्यवधान") का उपयोग करें। पारंपरिक टिकाऊ संदेश कतारों के विपरीत, जो निश्चित रूप से मुफ्त में लॉक नहीं होते हैं, और वास्तव में आमतौर पर दर्द-रहित वितरित लेनदेन शामिल होते हैं

  3. बहुत ज्यादा नहीं। LMAX इसे बस के नीचे इस आधार पर फेंकता है कि कार्यभार अन्योन्याश्रित हैं; एक के परिणाम दूसरों के लिए मापदंडों को बदल देते हैं। यह एक महत्वपूर्ण चेतावनी है, और एक जिसे फाउलर स्पष्ट रूप से बताते हैं। वे फेलओवर क्षमताओं को प्रदान करने के लिए कुछ संगामिति का उपयोग करते हैं, लेकिन सभी व्यावसायिक तर्क एक ही धागे पर संसाधित होते हैं ।

LMAX उच्च-स्तरीय OLTP का एकमात्र तरीका नहीं है। और यद्यपि यह अपने आप में काफी शानदार है, आपको प्रदर्शन के उस स्तर को खींचने के लिए रक्तस्राव-धार तकनीकों का उपयोग करने की आवश्यकता नहीं है।

उपरोक्त सभी सिद्धांतों में, # 3 शायद सबसे महत्वपूर्ण और सबसे प्रभावी है, क्योंकि, स्पष्ट रूप से, हार्डवेयर सस्ता है। यदि आप ठीक से आधा दर्जन कोर और कई दर्जन मशीनों में कार्यभार का विभाजन कर सकते हैं, तो आकाश पारंपरिक पारम्परिक कम्प्यूटिंग तकनीकों की सीमा है। आप आश्चर्यचकित होंगे कि आप संदेश कतार और एक राउंड-रॉबिन डिस्ट्रीब्यूटर के अलावा कुछ भी नहीं कर सकते हैं। यह स्पष्ट रूप से LMAX के रूप में कुशल नहीं है - वास्तव में भी करीब नहीं है - लेकिन थ्रूपुट, विलंबता और लागत-प्रभावशीलता अलग-अलग चिंताएं हैं, और यहां हम विशेष रूप से थ्रूपुट के बारे में बात कर रहे हैं।

यदि आपके पास एक ही तरह की विशेष आवश्यकताएं हैं जो LMAX करता है - विशेष रूप से, एक साझा स्थिति जो एक व्यावसायिक वास्तविकता से मेल खाती है जैसा कि जल्दबाजी में डिजाइन की पसंद के विपरीत है - तो मैं उनके घटक की कोशिश करना चाहूंगा, क्योंकि मैंने बहुत कुछ नहीं देखा है और यह उन आवश्यकताओं के अनुकूल है। लेकिन अगर हम केवल उच्च मापदण्ड के बारे में बात कर रहे हैं, तो मैं आपसे वितरित प्रणालियों में और अधिक शोध करने का आग्रह करूंगा, क्योंकि वे आज अधिकांश संगठनों द्वारा उपयोग किए जाने वाले विहित दृष्टिकोण हैं (Hadoop और संबंधित परियोजनाएं, ESB और संबंधित आर्किटेक्चर, CQRS जो कि फेलर भी हैं। उल्लेख, और इसी तरह)।

SSDs भी गेम-चेंजर बनने जा रहे हैं; यकीनन, वे पहले से ही हैं। अब रैम के समान एक्सेस समय के साथ आपके पास स्थायी भंडारण हो सकता है, और हालांकि सर्वर-ग्रेड एसएसडी अभी भी बहुत महंगा है, वे अंततः गोद लेने की दर बढ़ने पर कीमत में कमी आएंगे। यह बड़े पैमाने पर शोध किया गया है और परिणाम बहुत दिमागदार हैं और केवल समय के साथ बेहतर हो जाएगा, इसलिए पूरे "स्मृति में सब कुछ रखें" अवधारणा बहुत कम महत्वपूर्ण है जितना कि इसका इस्तेमाल किया जा सकता है। इसलिए एक बार फिर, मैं जब भी संभव हो, संगामिति पर ध्यान देने की कोशिश करूँगा।


सिद्धांतों पर चर्चा सिद्धांतों अंतर्निहित है महान है और अपनी टिप्पणी उत्कृष्ट है और ... जब तक फाउलर की कागज नहीं था कैश अनजान एल्गोरिदम करने के लिए एक पाद टिप्पणी में एक संदर्भ था en.wikipedia.org/wiki/Cache-oblivious_algorithm (जो में अच्छी तरह से फिट बैठता है श्रेणी संख्या 1 जो आपने ऊपर दी है) मैं उन पर कभी ठोकर नहीं खाता। इसलिए ... आपके पास ऊपर दी गई प्रत्येक श्रेणी के संबंध में, क्या आप शीर्ष 3 चीजों के बारे में जानते हैं जो एक व्यक्ति को जानना चाहिए?
दाकोतह उत्तर

@ डाकोटा: जब तक मैंने डिस्क आई / ओ को पूरी तरह से समाप्त नहीं कर दिया, तब तक मैं कैश इलाके के बारे में चिंता करना शुरू नहीं करूंगा , जहां अधिकांश समय अनुप्रयोगों के विशाल बहुमत में प्रतीक्षा में बिताया जाता है। इसके अलावा, आपको "शीर्ष 3 चीजों से क्या मतलब है जो एक व्यक्ति को पता होना चाहिए"? शीर्ष 3 क्या, किस बारे में जानना है?
Aaronaught

RAM एक्सेस लेटेंसी (~ 10 ^ -9s) से मैग्नेटिक डिस्क लेटेंसी (~ 10 ^ -3s औसत-केस) की छलांग 1000x से अधिक परिमाण के कुछ अन्य आदेश हैं। यहां तक ​​कि एसएसडी के पास अभी भी सैकड़ों बार माइक्रोसेकंड में मापा जाता है।
परदेशी विदेशी

@Sedate: लेटेंसी हाँ, लेकिन यह कच्चे विलंबता की तुलना में थ्रूपुट का अधिक प्रश्न है, और एक बार जब आप पिछले एक्सेस बार और कुल ट्रांसफर गति में पहुंच जाते हैं, तो डिस्क बहुत खराब नहीं होती हैं। इसलिए मैंने यादृच्छिक और अनुक्रमिक पहुंच के बीच अंतर किया; रैंडम एक्सेस परिदृश्यों के लिए यह है मुख्य रूप से एक विलंबता मुद्दा बन।
Aaronaught

@ चेतावनी: दोबारा पढ़ने पर, मुझे लगता है कि आप सही हैं। शायद एक बिंदु बनाया जाना चाहिए कि सभी डेटा एक्सेस यथासंभव अनुक्रमिक होना चाहिए; रैम से डेटा इन-ऑर्डर एक्सेस करते समय महत्वपूर्ण लाभ भी हो सकते हैं।
परदेशी विदेशी

10

मुझे लगता है कि इससे सीखने के लिए सबसे बड़ा सबक यह है कि आपको मूल बातें शुरू करनी चाहिए:

  • अच्छा एल्गोरिदम, उपयुक्त डेटा संरचनाएं, और कुछ भी नहीं करना "वास्तव में बेवकूफ"
  • अच्छी तरह से तथ्यात्मक कोड
  • प्रदर्शन का परीक्षण

प्रदर्शन परीक्षण के दौरान, आप अपना कोड प्रोफाइल करते हैं, अड़चनों का पता लगाते हैं, और उन्हें एक-एक करके ठीक करते हैं।

बहुत से लोग "उन्हें एक-एक करके ठीक करें" भाग पर सही कूदते हैं। वे "जावा संग्रह के कस्टम कार्यान्वयन" लिखने में समय व्यतीत करते हैं, क्योंकि वे सिर्फ इतना जानते हैं कि कैश मिस होने के कारण उनका सिस्टम धीमा है। यह एक योगदान कारक हो सकता है, लेकिन अगर आप निम्न-स्तरीय कोड को ट्विक करने के लिए सही कूदते हैं, तो आपको ArrayList का उपयोग करने के बड़े मुद्दे को याद करने की संभावना है जब आपको लिंक्डलिस्ट का उपयोग करना चाहिए, या यह कि आपका सिस्टम वास्तविक कारण है धीमा इसलिए है क्योंकि आपका ORM एक इकाई के आलसी-लोडिंग बच्चे हैं और इस प्रकार हर अनुरोध के लिए डेटाबेस में 400 अलग-अलग यात्राएं करते हैं।


7

LMAX कोड पर विशेष रूप से टिप्पणी नहीं करेंगे क्योंकि मुझे लगता है कि यह बहुत ही निराशाजनक है, लेकिन यहां उन चीजों के कुछ उदाहरण हैं जो मैंने किए हैं जो महत्वपूर्ण औसत दर्जे के प्रदर्शन में सुधार हुए हैं।

हमेशा की तरह, ये ऐसी तकनीकें हैं जिन्हें एक बार लागू करने के बाद आपको पता होना चाहिए कि आपको समस्या है और प्रदर्शन में सुधार करने की आवश्यकता है - अन्यथा आप समय से पहले अनुकूलन करने की संभावना रखते हैं।

  • सही डेटा संरचना का उपयोग करें, और यदि आवश्यक हो तो एक कस्टम बनाएं - सही डेटा संरचना डिज़ाइन आपके द्वारा माइक्रो-ऑप्टिमाइज़ेशन से प्राप्त किए गए सुधार को बौना कर देगा, इसलिए पहले ऐसा करें। यदि आपका एल्गोरिथ्म बहुत तेज़ ओ (1) यादृच्छिक अभिगमन पर प्रदर्शन के लिए निर्भर करता है, तो सुनिश्चित करें कि आपके पास एक डेटा संरचना है जो इसका समर्थन करता है! यह अधिकार प्राप्त करने के लिए कुछ हुप्स के माध्यम से कूदने के लायक है, उदाहरण के लिए एक तरीका है कि आप अपने डेटा को बहुत तेजी से हे (1) अनुक्रमित रीड का दोहन करने के लिए एक सरणी में प्रतिनिधित्व कर सकते हैं।
  • मेमोरी एक्सेस की तुलना में सीपीयू तेज है - यदि आप L1 / L2 कैश में मेमोरी नहीं है, तो एक रैंडम मेमोरी रीड करने में लगने वाले समय में आप काफी कैलकुलेशन कर सकते हैं। यह आम तौर पर गणना करने के लायक है अगर यह आपको पढ़ने की स्मृति को बचाता है।
  • JIT कम्पाइलर को अंतिम रूप देने में मदद करें - फ़ील्ड, विधियाँ और फ़ाइनल फाइनल विशिष्ट अनुकूलन को सक्षम करते हैं जो वास्तव में JIT कंपाइलर की मदद करते हैं। विशिष्ट उदाहरण:

    • कंपाइलर मान सकता है कि एक अंतिम वर्ग में कोई उपवर्ग नहीं है, इसलिए वर्चुअल पद्धति कॉल को स्टेटिक मेथड कॉल में बदल सकते हैं
    • संकलक एक अच्छा प्रदर्शन सुधार के लिए स्थिर के रूप में स्थैतिक अंतिम क्षेत्रों का इलाज कर सकता है, खासकर यदि निरंतर का उपयोग गणनाओं में किया जाता है जिसे संकलन समय पर गणना की जा सकती है।
    • यदि एक जावा ऑब्जेक्ट युक्त फ़ील्ड को अंतिम रूप दिया गया है, तो ऑप्टिमाइज़र नल चेक और वर्चुअल विधि प्रेषण दोनों को समाप्त कर सकता है। अच्छा लगा।
  • संग्रह की कक्षाओं को सरणियों से बदलें - यह कम पठनीय कोड में परिणामित होता है और बनाए रखने के लिए मुश्किल होता है, लेकिन लगभग हमेशा तेज होता है क्योंकि यह अप्रत्यक्षता की एक परत को हटाता है और बहुत से अच्छे सरणी-एक्सेस ऑप्टिमाइज़ेशन से लाभ देता है। आमतौर पर आंतरिक छोरों / प्रदर्शन संवेदनशील कोड में एक अच्छा विचार के बाद आप इसे एक अड़चन के रूप में पहचान चुके हैं, लेकिन पठनीयता के लिए अन्यथा से बचें!

  • जहाँ भी संभव हो आदिम का प्रयोग करें - आदिम मूल रूप से अपने वस्तु-आधारित समकक्षों की तुलना में तेजी से होते हैं। विशेष रूप से, मुक्केबाजी एक बड़ी मात्रा में उपरि जोड़ता है और यह बुरा जीसी ठहराव का कारण बन सकता है। यदि आप प्रदर्शन / विलंबता की परवाह करते हैं तो किसी भी आदिम को बॉक्सिंग की अनुमति न दें।

  • लो-लेवल लॉकिंग कम से कम करें- लो लेवल पर लॉक बहुत महंगे होते हैं। या तो पूरी तरह से लॉक होने से बचने के तरीके खोजें, या मोटे-मोटे स्तर पर लॉक करें ताकि आपको केवल डेटा के बड़े ब्लॉक पर बार-बार लॉक करने की जरूरत पड़े और लो-लेवल कोड लॉकिंग या कंसिस्टेंसी मुद्दों पर चिंता किए बिना आगे बढ़ सके।

  • मेमोरी को आवंटित करने से बचें - यह वास्तव में आपको समग्र रूप से धीमा कर सकता है क्योंकि जेवीएम कचरा संग्रह अविश्वसनीय रूप से कुशल है, लेकिन अगर आप बेहद कम विलंबता की ओर जाने की कोशिश कर रहे हैं और जीसी ठहराव को कम करने की कोशिश कर रहे हैं तो यह बहुत उपयोगी है। विशेष डेटा संरचनाएं हैं जो आप आवंटन से बचने के लिए उपयोग कर सकते हैं - विशेष रूप से http://javolution.org/ पुस्तकालय इन के लिए उत्कृष्ट और उल्लेखनीय है।

मैं तरीकों को अंतिम बनाने से असहमत हूं । जेआईटी यह पता लगाने में सक्षम है कि एक विधि कभी भी ओवरराइड नहीं होती है। इसके अलावा, यदि उपवर्ग बाद में लोड हो जाता है तो यह अनुकूलन को पूर्ववत कर सकता है। यह भी ध्यान दें कि "मेमोरी आवंटित करने से बचें" जीसी का काम भी कठिन बना सकता है और इस तरह आपको धीमा कर सकता है - इसलिए सावधानी के साथ उपयोग करें।
Maaartinus

@maaartinus: finalकुछ JIT के बारे में यह पता लग सकता है, अन्य नहीं। यह कार्यान्वयन पर निर्भर है (जैसा कि कई प्रदर्शन ट्यूनिंग युक्तियां हैं)। आवंटन के बारे में सहमत हों - आपको इसे बेंचमार्क करना होगा। आमतौर पर मैंने पाया है कि आवंटन को समाप्त करना बेहतर है, लेकिन YMMV।
मीका

4

पहले से ही हारूनहट से एक उत्कृष्ट जवाब में कहा गया है कि मैं उस कोड को नोट करना चाहूंगा जैसे कि विकसित करना, समझना और डीबग करना काफी मुश्किल हो सकता है। "बहुत कुशल होते हुए भी ... यह बहुत आसान है ..." LMAX ब्लॉग में उल्लिखित उनके दोस्तों में से एक के रूप में ।

  • पारंपरिक प्रश्नों और तालों के लिए उपयोग किए जाने वाले डेवलपर के लिए, एक नए दृष्टिकोण के लिए कोडिंग करना जंगली घोड़े की सवारी करने जैसा महसूस हो सकता है। कम से कम यह है कि मेरे अपने अनुभव जब साथ प्रयोग कर रहा था Phaser जो अवधारणा LMAX तकनीकी पत्र में बताया गया है। उस अर्थ में मैं कहूंगा कि यह दृष्टिकोण डेवलपर मस्तिष्क विवाद के लिए लॉक विवाद को रोकता है

ऊपर दिए गए, मुझे लगता है कि डिस्प्रेटर और इसी तरह के दृष्टिकोणों को चुनने वाले बेहतर सुनिश्चित करते हैं कि उनके पास अपने समाधान को बनाए रखने के लिए पर्याप्त विकास संसाधन हैं।

कुल मिलाकर, विघटनकारी दृष्टिकोण मुझे काफी आशाजनक लगता है। यहां तक ​​कि अगर आपकी कंपनी इसे ऊपर बताए गए कारणों के लिए उपयोग नहीं कर सकती है, तो अपने प्रबंधन को इसे (और सामान्य रूप से SEDA ) के अध्ययन में कुछ प्रयास "निवेश" करने के लिए आश्वस्त करने पर विचार करें - क्योंकि यदि वे नहीं करते हैं तो एक मौका है कि एक दिन उनके ग्राहक उन्हें 4x, 8x आदि कम सर्वरों की आवश्यकता वाले कुछ और प्रतिस्पर्धी समाधान के पक्ष में छोड़ देंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.