الموضوع نتيجة بحث فى صفحات كتير على الانترنت يعنى انا مش مخترعه وهحاول على قدر الإمكان اذكر المصادر لكن لو مذكرتهاش كلها هيبقى غصب عنى اكيد
Distributed memory object caching system هى
dynamic database driven websites يستخدم بصفة رئيسبة فى تخسين أداء ال
للداتابيز فبدلا من عمل نداءات للداتبيز نفسها يتم الحصول على الداتا من الذاكرة calls للداتبيز فى الذاكرة لتقليل الوقت الازم لعمل caching عن طريق عمل
تواجه ضغطا رهيبا على سيرفراتها لأن عدد الزائرين يوميا كان مهولا فلجأت لهذه الفكرة livejournal.com هذه الفكرة جاءت عندما كانت أحد الشركات وهى
وكانت النتائج مذهلة بالطبع حيث انخفض الضغط على الداتابيز سيرفرز لها بشكل كبير جدا
حتى مع وجود ضغط كبير فلها سرعة كبيرة فنحن نتعامل مع الرام للجهاز وهى سريعة للغاية
وسرعة الاستجابة للمستخدم أيضا تكون جيدة جدا
التى يمكنها التعامل معها بعدة لغات برمجة مختلفةclients عموما يمكنك مراجعة هذه الصفحة
لمزيد من المعلوما عن هذه السيرفرات وال
http://code.google.com/p/memcached/memcached server الموقع الرئيسى ل
http://www.danga.com/memcached/ نفسها tokyocabinet ولكننا سنقصر بحثنا هذا على وجود هذه الخاصية فى ال
memcahing servers هناك أنواع من ال
بعض العيوب لمثل هذه السيرفراتhttp://www.lshift.net/blog/2009/05/21/memcached-protocol-is-not-enough#more-416ممكن اتناول اللى جاء فى الموضوع ده بشىء من الإيجاز واللى عايز أكتر ممكن يقرأه
Memcached ought to be a caching layer
يعنى لو السيرفر وقف طبعا الكاششينج ده هيتوقف
لكن لو بيتم التعامل معاه على انه caching layer وده هيبقى مقبول لو انت بتتعامل مع فده مش هيبقى مقبول لانه كدة هتعمل بطء شديد فى السيرفرات عندك لو مش شغالة
persistent storage. السيرفر على انه
لمزيد من الفهم شوف المثال ده ومتقلقش لاننا هنوضحه بعد كدة المهم الفكرة العامة
>>> mc.set('key', 'value')
True
>>> os.system(’killall memcached’)
>>> mc.set(’key’, ‘value2′)
False # this's normal
But for example a ruby client , just ignore errors:
irb(main):003:0> cache = MemCache::new '127.0.0.1:11211'
irb(main):004:0> cache["key"] = “value”
=> “value”
$ killall memcached
irb(main):005:0> cache["key"] = “value”
=> “value” --> This's not accepted if we're using memcache as a persistent storage got the idea ? !!
(2) Optimistic locking: versioning
واحد key بيعملو ابديت ل client تخبل عند كذا
race condition كدة هيبقى عندك
version numbers for records والحل
def versioned_set(key, value):
version = mc.incr(’%s.version’ % (key,))
return mc.set(’%s.%s’ % (key, version), value)
def versioned_get(key):
version = mc.get(’%s.version’ % (key,))
return mc.get(’%s.%s’ % (key, version))
اعتقد الكود واضح
set - incr operations ? ولكن عيب الطريقة دى مثلا بو الكونيكشن قطع واليوزر بين عمليتين implement for optimistic locking لوبكدة نكون عملنا
طبعا هتحصل فوضى
server side
علشان كدة انسب طريقة للموضوع ده اننا نعمله على ال
3 - memcached using text protocol is slower than using binary protocol
since it's longer and requires further processing fo text to detect
newline characters
علشان يتم التغلي على مثل هذه المشاكل binray protocol المهم انه الحل السحرى كان استخدام
text protocol specifications :
http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txtbinary protocol specifications :
http://code.google.com/p/memcached/wiki/MemcacheBinaryProtocolخد بالك الموقع اللى فات ده مليان معلومات عن الموضوع ده وده مصدر رئيسى للتوتوريال دى
لازم نستخدم كلاينت يدعم الموضوع ده tokyotyrant او tokyocabinet المهم بقى
علشان نكلم
الموقع ده فى ليست بالكلاينتس اللى ممكن تستخدمهم ف لغات برمجة عديدة
http://code.google.com/p/memcached/wiki/Clientsاللى يهمن البايثون وهناخد أول واحد فى الليست الخاصة بلغة بايثون
من ftp client نزل الكود باستخدام اى
http://ftp://ftp.tummy.com/pub/python-memcachedpython setup.py build
python setup.py install
example on usage
#!/usr/bin/env python
import pytc as tc
import memcache
mc = memcache.Client(['127.0.0.1:1978'], debug=0)
bTreeDataBase = tc.BDB()
bTreeDataBase.open("dict.db", tc.BDBOWRITER | tc.BDBOCREAT)
bTreeDataBase.put("key1", "1")
bTreeDataBase.put("key2", "2")
mc.set("some_key", "Some value")
value = mc.get("some_key")
mc.set("another_key", 3)
mc.delete("another_key")
mc.set("key", "1") # note that the key used for incr/decr must be a string.
mc.incr("key")
mc.decr("key")
def getMyValue(key):
obj = mc.get(key) #trying to get from memcache
if not obj:# if not try to get from database but 1st add it to memcache
valFromDatabase = tc.get(key)
mc.set(key, valFromDatabase) # may be in another thread for no end-user latency
return tc.get(key)
def setMyValue(key, value): # set key,value ppair or update them
if mc.set(key, value):
tc.set(key, value) # may be in another thread
print(getMyValue("key"))
# similarly when deleting an item, we 1st delete it from cache then database
شوية حاجات لازم توضع فى الاحتياط عندما تتعامل مع مثل هذه الكلاينتس
والكلاينت الذا شرحناه بالإعلى لا يستخدم ذلك لسوء الحظ binary protocol يفضل
استخدام كلاينت يتعامل مع
binaryu protocol ممكن تجرب الكلاينت التالى وهو يتعامل مع
svn checkout http://ziutek.googlecode.com/svn/trunk/ binmemcache
هناك الأولitems وتشوف ال cache على الداتابيز لازم تشيك الأول على ال query
قبل أى
لو موجودة رجعها لو مش موجوده هاتها وحطها فى الكاش بعدين رجعها لليوزر
ولكن هذا الكلام لو انت بتتعامل مع داتابيز تانية partial updates لا تدعم ال tokyocabinet لو حد بيعمل ابديت لحاجة معينة وللأسف
من الكاش وبعدين اعملها ابديت وبكدة لما ييجى المستخدم يجيبها مش هتبقى فى الكاش فتيجى من الداتابيز وتتحط فى الكاش نسخة محدثة منها item امسح ال
udp او tcp الاتصال بين الكلاينت و السيرفر ممكن يبقى
بدل ما يقفلوها ويفتحوها كل شوية connections ويستحسن للكلاينتس أن تقوم بعمل كاشينج لل
مجهزة للتعامل مع أكثر من ألف اتصال memcaching servers كمان لازم تعرف انه ال overhead لأن ده بيسبب
establishing connections is an overhead, so caching them is efficient
لازم تأمنها كويس ومتسمحش لأجهزةمن برة النتورك بتاعتها بأخذ أكسس عليها
memcaching servers وأخيرا لازم تعرف انه ال