**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);
 }
 }

```

Այս հարցումը կթարմացնի քեշավորված տվյալները, եթե միայն տվյալների բազայի թարմացման հարցումը հաջող է ընթացել։ Հակառակ դեպքում, քեշը չի թարմանա։

Այս խնդիրն ունի նաև այլ լուծում։ Թարմացման ժամանակ հարկավոր է ոչ թե թարմացնել եզակի բանալիով քեշը, այլ հեռացնել այն։ Տվյալները ստանալու ժամանակ սպասարկիչը չի գտնի այդ բանալիով քեշը, ուստի հարցում կկատարի տվյալների բազային և նոր, թարմացված տվյալները կտեղադրի քեշում։ Նմանատիպ ձևով է իրականացվում նաև տվյալների բազայից տվյալների հեռացումը։

Տես նաև
-------

* PHP արագացուցիչ

Ծանոթագրություններ
------------------

1. ↑  InfoQ: JGroups Implementation of Memcached Supports Failover and JMX
2. ↑

Արտաքին հղումներ
----------------

* Նախագծի կայքը
* Մշակողի կայքի
* Distributed Caching with Memcached by Brad Fitzpatrick
* Memcached для windows