Questo post è un seguito di questa domanda: PHP Atomic Memcache su StackOverflow.
Considerando che sto usando Memcache (no alla fine) su PHP 5.3.10, ho implementato un sistema di blocco personalizzato in cui un client attenderà che una chiave di blocco venga distrutta prima che inizi a modificare una chiave su memcache.
Quindi:
Client 1 connects, checks for an active lock on key 1, finds none, and gets the data
Client 2 connects a few microsecond after Client 1, requests the same data from key 1,
but finds a lock
Client 2 enters a retry loop until Client 1 releases the lock
Client 1 saves new data to key 1, releases the lock
Client 2 gets the fresh data, sets a lock on key 1, and continues
Questo funziona il 90% delle volte. Funzionerebbe il 100% del tempo se due richieste sono fatte distanti tra loro (diciamo 500ms). Ma diciamo che due richieste sono fatte quasi allo stesso tempo (da 10 a 100 microsecondi a parte) la soluzione di cui sopra non riesce, ed entrambi i client scrivono sulla stessa chiave, risultando in dati errati.
Ho provato molte cose, tra cui un ciclo che varia nel tempo di attesa ogni iterazione:
while(/*lock key exists*/)
{
usleep(mt_rand(1000,100000);
}
Questo aiuta solo un po '.
Quale sarebbe la soluzione a questo particolare problema? Questi processi di mecache devono essere atomici. Sono disposto a tollerare un tasso di errore dell'1% (poiché significa che devo solo lavorare un po 'più duramente per farlo 0), ma qualsiasi altra cosa è troppo rischiosa.
Mi sono rotto la testa cercando di capirlo. Non è possibile eseguire l'upgrade a Memcached e le modifiche del valore non sono semplici (non sono incrementi)