Usually, programmers use technologies for their intended purpose, but I decided to conduct an experiment and try to use the memcached server as a scalable temporary key = value store.
Memcached is designed for simple caching of static data, because it does not provide a system for avoiding collisions.
Data recording
Standard situation
Suppose that our PHP application runs on a single server, and memcached runs on a remote machine. We can easily read and write to the same cell, because the application is not WEB, so the process is one. Due to the linearity of the process, it will not be able to simultaneously write different data to the same cell.
Two or more processes
Today we needed to split the application into two servers and problems started. There were collisions while writing to memcache. It turned out that in 80% of cases, applications try to simultaneously write their data into one cell. The ideal solution would be to use shared memory, but it does not scale in contrast to Memcached. Due to the large amount of code and the estimated time for rewriting applications, it was decided to add a crutch.
Read-Write AgloRtim
Imagine that two daemons are accessing a single data cell at the same moment for writing, which is inevitable. Under normal conditions, we get a collision. We will act like this:
')
- Process1 reads uniqid from the memory cell, it is empty.
- Process1 writes uniqid with its pid and server number
- Process1 checks the uniqid value. If it matches its key, writes the data.
Depending on the situation, removes the key. You can add the recording time, which will unlock the data cell when the process terminates abnormally 1 - Process2 reads uniqid from a memory location; it is not empty.
- Process2 waits, for example, usleep (rand (1.5)); (cyclically) in case you need to record data despite access to the cell of a neighboring object. We may not need to write, but just lock the cell to disable recording.
- Process2 reads uniqid from the memory cell, it is empty. Further, the same as with the first process.
- Process3 reads uniqid from the memory cell, it is empty.
- Process3 writes uniqid with its pid and server number
- Process3 checks the uniqid value. It does not match his key.
- Process3 returns an error, or acts as something else according to an algorithm.
- After recording, the processes should remove the pid from uniqid (it depends on the situation)
The test results of two demons overwriting the same cell in memcache with different PIDs.
:
: 17699
: 100000
: 89.012994 .
:
: 92999
: 100000
: 139.522396 .
Daemon Algorithm:
- while the mutex is closed, check again.
- if the mutex is open, write your mutex.
- if the mutex is correct, we write; if the wrong one, go to the beginning.
- We write data
- delete mutex
From the tests it is clear that almost half of the data was lost.
For normal developers: Redis, MemcacheDB and the like, we still have to rewrite this miracle.
With this algorithm, Memcache can even be used as a
Gearman . Disadvantages of the caching server itself remain, but in most cases they do not appear.