2011-06-28 25 views
11

में डुप्लिकेशन के साथ काम करना मैं अपने प्रोग्रामर के साथ इस बारे में जाने का सबसे अच्छा तरीका बता रहा हूं। हमारे पास डेटा है जो प्रति सेकंड लगभग 10000 वस्तुओं की दर से आता है। इसे असीमित रूप से संसाधित करने की आवश्यकता है, लेकिन ढीला क्रम पर्याप्त है, इसलिए प्रत्येक ऑब्जेक्ट को कई संदेश कतारों में से एक में राउंड-रॉबिन-लाइ डाला जाता है (कई उत्पादक और उपभोक्ता भी हैं)। प्रत्येक वस्तु ~ 300 बाइट है। और इसे टिकाऊ होने की जरूरत है, इसलिए एमक्यू डिस्क पर बने रहने के लिए कॉन्फ़िगर किए गए हैं।संदेश कतार

समस्या यह है कि अक्सर इन वस्तुओं को डुप्लिकेट किया जाता है (जैसा कि वे उत्पादक में आने वाले डेटा में अपरिहार्य रूप से डुप्लिकेट किए जाते हैं)। उनके पास 10-बाइट अद्वितीय आईडी हैं। कतार में ऑब्जेक्ट्स डुप्लिकेट किए जाने पर यह विनाशकारी नहीं है, लेकिन ऐसा होता है कि कतार से लिया जाने के बाद प्रसंस्करण में डुप्लीकेट किया जाता है। ऑब्जेक्ट्स के प्रसंस्करण में कोई डुप्लिकेशंस सुनिश्चित करने के दौरान रैखिक स्केलेबिलिटी के जितना संभव हो सके सुनिश्चित करने के बारे में जाने का सबसे अच्छा तरीका क्या है? और शायद उस से जुड़ा हुआ, क्या पूरे ऑब्जेक्ट को संदेश कतार में संग्रहीत किया जाना चाहिए, या केवल आईडी के साथ आईडी को कैसंड्रा जैसे कुछ में संग्रहीत किया जाना चाहिए?

धन्यवाद!

संपादित करें: पुष्टि की गई कि डुप्लिकेशंस कहां होता है। इसके अलावा, अब तक मेरे पास रेडिस के लिए 2 सिफारिशें हैं। मैं पहले RabbitMQ पर विचार कर रहा था। मेरी आवश्यकताओं के संबंध में प्रत्येक के पेशेवर और विपक्ष क्या हैं?

+0

Redis बहुत तेजी से खुला स्रोत, उन्नत कुंजी-मान दुकान है।इसे अक्सर डेटा स्ट्रक्चर सर्वर के रूप में जाना जाता है क्योंकि कुंजी में तार, हैंश, सूचियां, सेट और सॉर्ट किए गए सेट हो सकते हैं। रेडिस में भी (बहुत) सक्रिय विकास होता है और यदि आप मुझसे पूछते हैं तो इसका उपयोग करना मजेदार है। मैंने कभी भी RabbitMQ के साथ खेला नहीं है। – Alfred

+0

मैं एक और रेडिस प्लग जोड़ूंगा। मैंने हाल ही में एक [ओपन-सोर्स संदेश कतार परियोजना] विकसित किया है (http://jordanhalterman.github.com/redmq/) जो मूल रूप से एक और भंडारण विधि (अनामित रहने के लिए) के साथ शुरू हुआ। परियोजना के माध्यम से लगभग आधा रास्ता मैंने रेडिस पर जाने का फैसला किया। मैंने इसे अविश्वसनीय रूप से तेज़, बहुत विश्वसनीय, सीखने में आसान, और बुनियादी और जटिल संदेश प्रणाली दोनों के निर्माण के लिए बहुत उपयोगी सुविधाओं के साथ पाया। – kuujo

उत्तर

2

यह जानने के बिना कि सिस्टम के भीतर संदेशों को कैसे बनाया जाता है, निर्माता द्वारा कतार में प्रकाशित करने के लिए निर्माता का उपयोग किया जाता है, और कतार प्रणाली के साथ जानना उपयोग में है, यह पता लगाना मुश्किल है कि क्या हो रहा है।

मैंने देखा है कि यह परिदृश्य कई अलग-अलग तरीकों से होता है; टाइम-आउट श्रमिकों को कतार में संदेश फिर से दिखाई देने का कारण बनता है (और इस प्रकार दूसरी बार संसाधित होता है, यह केस्ट्रल के साथ आम है), गलत कॉन्फ़िगर किए गए ब्रोकर (एचए एक्टिव एमक्यू दिमाग में आता है), गलत कॉन्फ़िगर किए गए क्लाइंट (स्प्रिंग प्लस कैमल रूटिंग दिमाग में आता है) , ग्राहकों को दोबारा जमा करने आदि। इस तरह की समस्या आ सकती है।

चूंकि मैं वास्तव में इस मुद्दे का निदान नहीं कर सकता, इसलिए मैं redis प्लग कर दूंगा। आप आसानी से (जो ओ (1) है, जैसा कि एसएडीडी है) pub/sub के साथ अविश्वसनीय रूप से तेज़, निरंतर समय, डुप्लिकेट मुक्त (सेट में अद्वितीय तत्व होना चाहिए) कतार के साथ आसानी से कुछ जोड़ सकते हैं। हालांकि यह एक रूबी परियोजना है, resque मदद करने में सक्षम हो सकता है। यह कम से कम देखने लायक है।

शुभकामनाएं।

+0

Redis @bmatheny के आपके सुझाव के लिए धन्यवाद! बस जांचें .. एसपीओपी और पब/सब के संयोजन से क्या आप निर्माता को एसएडीडी सेट पर सेट करते हैं, फिर उपभोक्ताओं को अतिरिक्त के बारे में सूचित करने के लिए प्रकाशित करें? साथ ही, अगर मैं सेट पर आईडी को एसएडीडी कर रहा हूं, तो बाकी ऑब्जेक्ट डेटा को व्यक्त करने का सबसे अच्छा तरीका क्या है? – Max

+1

निर्भर करता है कि आप इसे कैसे कार्यान्वित करना चाहते हैं। यदि आप एनओयूपी उपभोक्ताओं (उपभोक्ताओं के लिए कोई काम नहीं है, यह एक सर्वेक्षण मॉडल है) तो आप उपभोक्ताओं/उत्पादकों के लिए केवल एसपीओपी और एसएडीडी का उपयोग कर सकते हैं। आप BLPOP का भी उपयोग कर सकते हैं (जो डेटा उपलब्ध होने तक अवरुद्ध होगा) लेकिन यह केवल सूचियों के लिए उपलब्ध है, जिसमें डुप्लिकेट हो सकते हैं। पब/उप कार्यान्वयन सूचियों से स्वतंत्र है, इसलिए संभावित रूप से डुप्लिकेश हो सकते हैं। यदि आप डुप्लिकेट को खत्म करना चाहते हैं, तो सेट के साथ चिपकें और उपभोक्ताओं को मतदान करें। – bmatheny

3

पुनश्च: यह मेरे जीवन में पहली बार है कि Redis वेबसाइट समस्या हो रही है, लेकिन मुझे यकीन है जब आप इसे पर जाते हैं, वे समस्या

समाधान कर लिया है
> We have data that comes in at a rate 
> of about 10000 objects per second. 
> This needs to be processed 
> asynchronously, but loose ordering is 
> sufficient, so each object is inserted 
> round-robin-ly into one of several 
> message queues (there are also several 
> producers and consumers) 

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

सबसे पहले मैं आपको अपने लैपटॉप के बारे में जानकारी दिखाना पसंद करता हूं (मुझे यह पसंद है, लेकिन एक बड़ा सर्वर बहुत तेज़ होगा;))। मेरे पिता (थोड़ा सा प्रभावित हुआ :)) ने हाल ही में एक नया पीसी खरीदा और यह मेरे लैपटॉप को मुश्किल से धड़कता है (8 सीपीयू की बजाय 2)।

[email protected]:~/database/redis-2.2.0-rc4/src$ ./redis-benchmark 
====== PING (inline) ====== 
    10000 requests completed in 0.22 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

94.84% <= 1 milliseconds 
98.74% <= 2 milliseconds 
99.65% <= 3 milliseconds 
100.00% <= 4 milliseconds 
46296.30 requests per second 

====== PING ====== 
    10000 requests completed in 0.22 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

91.30% <= 1 milliseconds 
98.21% <= 2 milliseconds 
99.29% <= 3 milliseconds 
99.52% <= 4 milliseconds 
100.00% <= 4 milliseconds 
45662.10 requests per second 

====== MSET (10 keys) ====== 
    10000 requests completed in 0.32 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

3.45% <= 1 milliseconds 
88.55% <= 2 milliseconds 
97.86% <= 3 milliseconds 
98.92% <= 4 milliseconds 
99.80% <= 5 milliseconds 
99.94% <= 6 milliseconds 
99.95% <= 9 milliseconds 
99.96% <= 10 milliseconds 
100.00% <= 10 milliseconds 
30864.20 requests per second 

====== SET ====== 
    10000 requests completed in 0.21 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

92.45% <= 1 milliseconds 
98.78% <= 2 milliseconds 
99.00% <= 3 milliseconds 
99.01% <= 4 milliseconds 
99.53% <= 5 milliseconds 
100.00% <= 5 milliseconds 
47169.81 requests per second 

====== GET ====== 
    10000 requests completed in 0.21 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

94.50% <= 1 milliseconds 
98.21% <= 2 milliseconds 
99.50% <= 3 milliseconds 
100.00% <= 3 milliseconds 
47619.05 requests per second 

====== INCR ====== 
    10000 requests completed in 0.23 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

91.90% <= 1 milliseconds 
97.45% <= 2 milliseconds 
98.59% <= 3 milliseconds 
99.51% <= 10 milliseconds 
99.78% <= 11 milliseconds 
100.00% <= 11 milliseconds 
44444.45 requests per second 

====== LPUSH ====== 
    10000 requests completed in 0.21 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

95.02% <= 1 milliseconds 
98.51% <= 2 milliseconds 
99.23% <= 3 milliseconds 
99.51% <= 5 milliseconds 
99.52% <= 6 milliseconds 
100.00% <= 6 milliseconds 
47619.05 requests per second 

====== LPOP ====== 
    10000 requests completed in 0.21 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

95.89% <= 1 milliseconds 
98.69% <= 2 milliseconds 
98.96% <= 3 milliseconds 
99.51% <= 5 milliseconds 
99.98% <= 6 milliseconds 
100.00% <= 6 milliseconds 
47619.05 requests per second 

====== SADD ====== 
    10000 requests completed in 0.22 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

91.08% <= 1 milliseconds 
97.79% <= 2 milliseconds 
98.61% <= 3 milliseconds 
99.25% <= 4 milliseconds 
99.51% <= 5 milliseconds 
99.81% <= 6 milliseconds 
100.00% <= 6 milliseconds 
45454.55 requests per second 

====== SPOP ====== 
    10000 requests completed in 0.22 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

91.88% <= 1 milliseconds 
98.64% <= 2 milliseconds 
99.09% <= 3 milliseconds 
99.40% <= 4 milliseconds 
99.48% <= 5 milliseconds 
99.60% <= 6 milliseconds 
99.98% <= 11 milliseconds 
100.00% <= 11 milliseconds 
46296.30 requests per second 

====== LPUSH (again, in order to bench LRANGE) ====== 
    10000 requests completed in 0.23 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

91.00% <= 1 milliseconds 
97.82% <= 2 milliseconds 
99.01% <= 3 milliseconds 
99.56% <= 4 milliseconds 
99.73% <= 5 milliseconds 
99.77% <= 7 milliseconds 
100.00% <= 7 milliseconds 
44247.79 requests per second 

====== LRANGE (first 100 elements) ====== 
    10000 requests completed in 0.39 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

6.24% <= 1 milliseconds 
75.78% <= 2 milliseconds 
93.69% <= 3 milliseconds 
97.29% <= 4 milliseconds 
98.74% <= 5 milliseconds 
99.45% <= 6 milliseconds 
99.52% <= 7 milliseconds 
99.93% <= 8 milliseconds 
100.00% <= 8 milliseconds 
25906.74 requests per second 

====== LRANGE (first 300 elements) ====== 
    10000 requests completed in 0.78 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

1.30% <= 1 milliseconds 
5.07% <= 2 milliseconds 
36.42% <= 3 milliseconds 
72.75% <= 4 milliseconds 
93.26% <= 5 milliseconds 
97.36% <= 6 milliseconds 
98.72% <= 7 milliseconds 
99.35% <= 8 milliseconds 
100.00% <= 8 milliseconds 
12886.60 requests per second 

====== LRANGE (first 450 elements) ====== 
    10000 requests completed in 1.10 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

0.67% <= 1 milliseconds 
3.64% <= 2 milliseconds 
8.01% <= 3 milliseconds 
23.59% <= 4 milliseconds 
56.69% <= 5 milliseconds 
76.34% <= 6 milliseconds 
90.00% <= 7 milliseconds 
96.92% <= 8 milliseconds 
98.55% <= 9 milliseconds 
99.06% <= 10 milliseconds 
99.53% <= 11 milliseconds 
100.00% <= 11 milliseconds 
9066.18 requests per second 

====== LRANGE (first 600 elements) ====== 
    10000 requests completed in 1.48 seconds 
    50 parallel clients 
    3 bytes payload 
    keep alive: 1 

0.85% <= 1 milliseconds 
9.23% <= 2 milliseconds 
11.03% <= 3 milliseconds 
15.94% <= 4 milliseconds 
27.55% <= 5 milliseconds 
41.10% <= 6 milliseconds 
56.23% <= 7 milliseconds 
78.41% <= 8 milliseconds 
87.37% <= 9 milliseconds 
92.81% <= 10 milliseconds 
95.10% <= 11 milliseconds 
97.03% <= 12 milliseconds 
98.46% <= 13 milliseconds 
99.05% <= 14 milliseconds 
99.37% <= 15 milliseconds 
99.40% <= 17 milliseconds 
99.67% <= 18 milliseconds 
99.81% <= 19 milliseconds 
99.97% <= 20 milliseconds 
100.00% <= 20 milliseconds 
6752.19 requests per second 

आप उम्मीद है कि मेरी सरल लैपटॉप बेंचमार्किंग से आप शायद सिर्फ एक संदेश कतार जरूरत है क्योंकि कर सकते हैं redis संभाल देख सकते हैं:

-Computer- 
Processor  : 2x Intel(R) Core(TM)2 Duo CPU  T7100 @ 1.80GHz 
Memory  : 2051MB (1152MB used) 
Operating System  : Ubuntu 10.10 
User Name  : alfred (alfred) 
-Display- 
Resolution  : 1920x1080 pixels 
OpenGL Renderer  : Unknown 
X11 Vendor  : The X.Org Foundation 
-Multimedia- 
Audio Adapter  : HDA-Intel - HDA Intel 
-Input Devices- 
Power Button 
Lid Switch 
Sleep Button 
Power Button 
AT Translated Set 2 keyboard 
Microsoft Comfort Curve Keyboard 2000 
Microsoft Comfort Curve Keyboard 2000 
Logitech Trackball 
Video Bus 
PS/2 Logitech Wheel Mouse 
-SCSI Disks- 
HL-DT-ST DVDRAM GSA-T20N 
ATA WDC WD1600BEVS-2 
भी ज्यादा redis अनुकूलन कर के बिना मेरे मशीन पर redis-benchmark का उपयोग कर मानक नीचे

0.23 सेकंड में 10000 lpush अनुरोध और 0.200 सेकंड में 10000 lpop अनुरोध। जब आपको केवल एक कतार की आवश्यकता होती है तो मेरा मानना ​​है कि आपकी समस्या अब कोई समस्या नहीं है (या निर्माता उत्पादक डुप्लीकेट बनाते हैं जिन्हें मैं पूरी तरह समझ नहीं पा रहा हूं?)।

> And it needs to be durable, so the MQs 
> are configured to persist to disk. 

रेडिस भी डिस्क पर बने रहते हैं।

> The problem is that often these 
> objects are duplicated. They do have 
> 10-byte unique ids. It's not 
> catastrophic if objects are duplicated 
> in the queue, but it is if they're 
> duplicated in the processing after 
> being taken from the queue. What's the 
> best way to go about ensuring as close 
> as possible to linear scalability 
> whilst ensuring there's no duplication 
> in the processing of the objects? 

एक संदेश कतार (बॉक्स) का उपयोग करते समय यह समस्या मौजूद नहीं है यदि मैं सही ढंग से समझता हूं। लेकिन यदि नहीं, तो आप बस यह जांच सकते हैं कि आईडी is member of your set ids है या नहीं। जब आप आईडी को संसाधित करते हैं तो आपको remove it from the set ids होना चाहिए। सबसे पहले आपको sadd का उपयोग करके सदस्यों को सूची में शामिल करना चाहिए।

यदि कोई बॉक्स अब स्केल नहीं करता है तो आपको अपनी चाबियाँ एकाधिक बॉक्स पर शेड करना चाहिए और उस बॉक्स पर उस कुंजी को देखना चाहिए। इस बारे में अधिक जानने के लिए मुझे लगता है कि आप निम्न लिंक पढ़ना चाहिए:

आप चाहिए सीधे स्मृति में अपने सभी जानकारी है क्योंकि कुछ भी नहीं के रूप में तेजी से स्मृति के रूप में चला सकते हैं यदि संभव हो तो (ठीक अपने cache स्मृति भी तेजी से, लेकिन वास्तव में वास्तव में छोटा है प्लस आप अपने कोड के माध्यम से उस तक नहीं पहुँच सकता) । रेडिस आपकी सारी जानकारी को मेमोरी के अंदर स्टोर करता है और डिस्क पर स्नैपशॉट बनाता है। मुझे लगता है कि आप अपनी सारी जानकारी को स्मृति के अंदर स्टोर करने में सक्षम होना चाहिए और पूरी तरह से कैसंड्रा जैसे कुछ का उपयोग करके छोड़ना चाहिए।

आइए मान लें कि प्रत्येक ऑब्जेक्ट प्रति ऑब्जेक्ट 40000 प्रति सेकंड = 4000000 बाइट प्रति सेकेंड => 4000000 बाइट प्रति सेकेंड = = 4 एमबी/एस की है, तो मेरी गणना सही है। आप आसानी से उस स्मृति की जानकारी को अपनी स्मृति के अंदर संग्रहीत कर सकते हैं। यदि आप वास्तव में संभवतः अपनी याददाश्त को अपग्रेड करने पर विचार नहीं कर सकते हैं, क्योंकि स्मृति अब महंगा नहीं है।

1

यदि आपको मिश्रण में Camel फेंकने की कोई बात नहीं है, तो आप इसके साथ मदद करने के लिए idempotent-consumer ईआईपी का उपयोग कर सकते हैं।

इसके अलावा, ActiveMQ Message Groups समूह संबंधित संदेश के लिए इस्तेमाल किया जा सकता है और उन्हें आसानी से डुप्लिकेट जांच करने के लिए और अभी भी बनाए रखने के उच्च throughput बनाने, आदि ...