Hintergrund
Viele Teams im Unternehmen haben kürzlich PHP7 aktualisiert. Derzeit ist die einzige Erweiterung, die das Lesen von PHP7 unterstützt, Memcached. Viele Projekte im Unternehmen teilen sich jedoch einen MC-Cluster zum Speichern und Abrufen von Benutzersitzungsdaten. Beim Speichern wird die Memcache-Erweiterung verwendet, um sie beim Anmelden in Form eines Arrays zu schreiben. Beim Lesen wird natürlich der Memcache verwendet Erweiterung, um es in Form eines Arrays auszulesen. Aber jetzt kann es nur noch mit Memcached gelesen werden. Aber meines Wissens sind die beiden beim Lesen von Daten in Array-Form nicht miteinander kompatibel, deshalb möchte ich herausfinden, warum.
Überprüfung
Überprüfen Sie, ob die Lese- und Schreibarraydaten der Memcache-Erweiterung und der Memcached-Erweiterung inkompatibel sind. Testskript:
<?php echo "========== test string ============\n"; $mc = new memcache; $mc->addServer('10.199.189.129', 11511); $key = 'testString'; $mc->set($key, 'test success'); var_dump($mc->get($key)); $mc2 = new memcached; $mc2->addServer('10.199.189.129', 11511); var_dump($mc2->get($key)); echo "========== test array ============\n"; $key2 = 'testArray'; $mc->set($key2, [1,2,3]); var_dump($mc->get($key2)); var_dump($mc2->get($key2));
Ausführungsergebnis:
➜ ~ php /apps/dat/test.php ========== test string ============ string(12) "test success" string(12) "test success" ========== test array ============ array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } int(0)
Nach den Ergebnissen zu urteilen, bestätigt es unsere vorherige Aussage.
Erraten Sie den Grund
Da es kein Problem mit der Zeichenfolge gibt, liegt das Problem im Array-Format. Daher vermute ich, dass die Serialisierungsmethode beim Speichern des Arrays in MC unterschiedlich ist. Also wurden weitere Tests durchgeführt: Schreiben Sie ein Testskript
<?php echo "========== test array ============\n"; $mc = new memcache; $mc->addServer('10.199.189.129', 11511); $mc2 = new memcached; $mc2->addServer('10.199.189.129', 11511); $key2 = 'testArray1'; $key3 = 'testArray2'; $mc->set($key2, [1,2,3]); $mc2->set($key3, [1,2,3]); var_dump($mc->get($key2)); var_dump($mc2->get($key3));
Ausführungsergebnisse:
➜ ~ php /apps/dat/test.php ========== test array ============ array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
Dann stellen Sie eine direkte Verbindung zu mc her, um es anzuzeigen
➜ ~ telnet 10.199.189.129 11511 Trying 10.199.189.129... Connected to 10.199.189.129 Escape character is '^]'. get testArray1 VALUE testArray1 1 30 a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} END get testArray2 VALUE testArray2 4 30 a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} END
Von der Ergebnisse Schauen Sie, wir können feststellen, dass die Ergebnisse des Memcache- und Memcached-Schreibens in MC gleich sind, was bedeutet, dass unsere Vermutung falsch ist. Die Serialisierungsverarbeitung der beiden Werte ist genau gleich, der Unterschied liegt in den unterschiedlichen Flags der Werte. Wenn Memcache Array-Daten speichert, ist Falg 1, während Memcached 4 ist. Wir wissen, dass das Flag des MC-Werts Benutzern zum Anpassen bereitgestellt wird, was eine unterschiedliche Verarbeitung beim Lesen erleichtert. Aber warum sind die Flaggendefinitionen der beiden unterschiedlich? Versuchen Sie vor diesem Hintergrund, den Grund herauszufinden, indem Sie den Quellcode der beiden Erweiterungen lesen.
Lesen Sie den Quellcode beider Erweiterungen
memcache
php_memcache.h:
#define MMC_SERIALIZED 1 #define MMC_COMPRESSED 2
memcached
php_memcached.c
#define MEMC_VAL_IS_STRING 0 #define MEMC_VAL_IS_LONG 1 #define MEMC_VAL_IS_DOUBLE 2 #define MEMC_VAL_IS_BOOL 3 #define MEMC_VAL_IS_SERIALIZED 4 #define MEMC_VAL_IS_IGBINARY 5 #define MEMC_VAL_IS_JSON 6 #define MEMC_VAL_IS_MSGPACK 7
Nachdem ich den Quellcode gelesen hatte, stellte ich fest, dass Memcache das Flag des Array-Formats als 1 definiert und Memcached den Datentyp als String, Long, definiert, um detaillierte Typunterscheidungen für die Werte vorzunehmen in mc von PHP gespeichert. Datentypen wie Double usw. Mit anderen Worten, wenn Sie Memcache verwenden, lautet das Ausführungsergebnis der Ausführung von
<?php $mc = new memcache; $mc->addServer('10.199.189.129', 11511); $mc->set('123',1); var_dump($mc->get('123'));
:
string(1) "1"
Sie haben offensichtlich einen Schlüssel mit dem Wert 1 gespeichert, aber manchmal ist es ein Zeichenfolge. Und wenn Sie Memcached verwenden, führen Sie
<?php$mc = new memcached; $mc->addServer('10.199.189.129', 11511); $mc->set('123',1); var_dump($mc->get('123'));
aus und das Ausführungsergebnis ist:
int(1)
Schlussfolgerung
Der Grund, warum die Memcache-Erweiterung und die Memcached-Erweiterung beim Lesen und Schreiben von Array-Daten nicht kompatibel sind, liegt darin, dass Memcached Bezeichner verschiedener Datentypen definiert, um Datentypen im Detail zu unterscheiden, und der Bezeichner des Arrays nicht mit dem Array-Bezeichner übereinstimmt definiert durch Memcache.
Um sicherzustellen, dass die direkt von der Memcache-Erweiterung und der Memcached-Erweiterung geschriebenen Daten sich gegenseitig lesen können, kann mc nur im String-Format geschrieben werden.
Nach dieser Erkundung wurde mir auch klar, dass Memcache in vielerlei Hinsicht besser ist als Memcache. Ich glaube, dass Memcache mit der Popularität von PHP7 schneller verschwinden wird.