Տեսակ | cache? և ազատ ծրագրային ապահովում |
---|---|
Նախագծումը՝ | Danga Interactive |
Գրված է՝ | Սի (ծրագրավորման լեզու)[1] |
ՕՀ | բազմապլատֆորմ |
Լույս տեսավ՝ | մայիսի 22, 2003 |
Արտոնագիր | BSD վերափոխված արտոնագիր[2] |
Կայք | memcached.org(անգլ.) |
Ելակոդ | github.com/memcached/memcached |
memcached, ծրագրային ապահովում, որն hash աղյուսակների նմուշի հիման վրա իրականացնում է տվյալների քեշավորում օպերատիվ հիշողության մեջ։
Տարբեր ծրագրավորման լեզուների (մասնավորապես, C/C++-ի, Ruby-ի, Perl-ի, PHP-ի, Python-ի, Java-ի, CSharp/.Net-ի և այլնի) համար գրադարանները թույլ են տալիս օպերատիվ հիշողությունում քեշավորել տվյալները գոյություն ունեցող սերվերներից մեծամասնությունում։ Բաշխումն իրականացվում է տվյալների սեգմենտավորման ճանապարհով՝ բանալու hash-ի արժեքով, ինչպես դա արվում է hash աղյուսակների սոկետներում։ Լեզվի գրադարանը, օգտագործելով տվյալների բանալին, հաշվարկում է hash-ը և օգտագործում է այն համապատասխանը սպասարկիչն ընտրելու համար։
memcached-ի API-ն ունի միայն աշխատանքի համար հիմնական ֆունկցիաները՝ սպասարկչի ընտրությունը, կապի հաստատումն ու խզումը, օբյեկտի ավելացումը, հեռացումը, թարմացումն ու ստացումը, ինչպես նաև Compare-and-swap ֆունկցիան։ Ցանկացած օբյեկտի համար սահմանվում է կյանքի տևողությունը՝ 1 վայրկյանից մինչև անվերջություն։ Հիշողության սպառման ժամանակ հին օբյեկտներն ավտոմատ հեռացվում են։ PHP-ն ունի նաև memcached-ի աշխատանքի համար պատրաստի PECL գրադարաններ, որոնք լրացուցիչ հնարավորություններ են տալիս։
Ուշադրություն դարձրեք, որ այս բաժնում ներկայացված բոլոր ֆունկցիաները գրված են փսևդոկոդով։ Memcached-ի լեզվի շարահյուսությունը, կախված օգտագործվող ծրագրավորման լեզվից և օգտագործվող API―ից, կարող է տարբեր լինել։
Տվյալների բազային սովորական հարցումը (առանց memcached-ի կիրառման) ունի հետևյալ տեսքը՝
function get_foo(int userid) {
result = db_select("SELECT * FROM users WHERE userid = ?", userid);
return result;
}
memcached-ի կիրառման ժամանակ այդ նույն հարցումը կունենա հետևյալ տեսքը՝
function get_foo(int userid) {
/* սկզբում ստուգում ենք քեշը */
data = memcached_fetch("userrow:" + userid);
/* եթե քեշում մեզ անհրաժեշտ տեղեկատվությունն բացակայում է */
if (!data) {
/* հարցում ենք անում տվյալների բազային */
data = db_select("SELECT * FROM users WHERE userid = ?", userid);
/* հետագա հարցումների համար արդյունքը պահպանում ենք քեշում */
memcached_add("userrow:" + userid, data);
}
return data;
}
Սպասարկիչը նախ ստուգում է, ունի՞ արդյոք Memcached-ը «userrow: userid» եզակի բանալիով արժեք, որտեղ userid-ն որևէ թիվ է (տվյալ օրինակում՝ օգտագործողի եզակի ID-ն)։ Եթե քեշը չունի այդպիսի տվյալներ, սպասարկիչը սովորական հարցում կկատարի տվյալների բազային և արդյունքը համապատասխան եզակի բանալիով կպահպանի քեշում։
Սակայն, եթե մենք օգտագործենք քեշի API―ին միայն այդ հարցումը, ապա տվյալների բազայի թարմացման ժամանակ memcached-ի տվյալները չեն թարմանա, և արդյունքում այն վերադարձնի հին տվյալներ։ Դրա համար տվյալների բազայի թարմացման ժամանակ պետք է թարմացնել նաև քեշը՝
function update_foo(int userid, string dbUpdateString) {
/* սկզբում թարմացնում ենք տվյալների բազան */
result = db_execute(dbUpdateString);
/* եթե տվյալների բազան թարմացված է */
if (result) {
/* ստանում ենք թարմացված տվյալներով տեղեկատվությունը բազայից */
data = db_select("SELECT * FROM users WHERE userid = ?", userid);
/* ^ Այս տողը կարող էր ունենալ նաև հետևյալ տեսքը՝ data = createDataFromDBString(dbUpdateString); */
/* թարմացված տվյալները տեղադրում ենք քեշում */
memcached_set("userrow:" + userid, data);
}
}
Այս հարցումը կթարմացնի քեշավորված տվյալները, եթե միայն տվյալների բազայի թարմացման հարցումը հաջող է ընթացել։ Հակառակ դեպքում, քեշը չի թարմանա։
Այս խնդիրն ունի նաև այլ լուծում։ Թարմացման ժամանակ հարկավոր է ոչ թե թարմացնել եզակի բանալիով քեշը, այլ հեռացնել այն։ Տվյալները ստանալու ժամանակ սպասարկիչը չի գտնի այդ բանալիով քեշը, ուստի հարցում կկատարի տվյալների բազային և նոր, թարմացված տվյալները կտեղադրի քեշում։ Նմանատիպ ձևով է իրականացվում նաև տվյալների բազայից տվյալների հեռացումը։