Рубрики
Uncategorized

Исследование несовместимости между расширением Memcache PHP и массивом чтения-записи расширения memcached

Автор оригинала: David Wong.

В последнее время многие команды в компании обновили php 7. В настоящее время только memcached является расширением, которое поддерживает php 7 для чтения mc. Однако многие проекты в компании совместно используют кластер MC для доступа к данным сеанса пользователя, которые записываются в виде массивов при входе в систему и естественным образом считываются в виде массивов при входе в систему. Но теперь для чтения можно использовать только memcached. Но, насколько я знаю, чтение данных массива несовместимо, поэтому я хочу выяснить, почему.

Убедитесь, что расширения Memcache и расширения memcached несовместимы со сценариями тестирования массивов данных для чтения и записи:

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

Результаты внедрения:

➜ ~ 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)

Судя по результатам, это подтверждает наше предыдущее утверждение.

Поскольку строка не имеет проблем, проблема заключается в формате массива. Таким образом, есть подозрение, что массив имеет разные методы сериализации, когда он хранится в 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));

Результаты внедрения:

➜ ~ 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) }

Затем подключитесь непосредственно к MC для просмотра

➜ ~ 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

Из результатов мы можем заключить, что результаты memcached и memcached, записанные в MC, одинаковы, то есть наше предположение неверно. Сериализация двух значений одинакова, но разница в том, что флаг значений отличается. Когда Memcache хранит данные массива, falg равен 1, а memcached равен 4. Мы знаем, что флаг MC median предоставляется пользователям для настройки и различной обработки, когда его легко прочитать снова. Но почему у них разные определения флага? Имея это в виду, попробуйте найти причину, прочитав исходный код двух расширений.

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

После прочтения исходного кода обнаруживается, что memcached определяет флаг массива array как 1, в то время как memcached определяет строковые, длинные, двойные и другие типы данных, чтобы подробно различать значения PHP, хранящиеся в MC. То есть, когда вы используете memcache, запустите

addServer('10.199.189.129', 11511); 
$mc->set('123',1); 
var_dump($mc->get('123'));

Результаты внедрения заключаются в следующем:

 string(1) "1"

Вы явно сохраняете ключ со значением 1, но считываете его как строку. И когда вы используете memcached, запустите

addServer('10.199.189.129', 11511); 
$mc->set('123',1); 
var_dump($mc->get('123'));

Результаты внедрения заключаются в следующем:

 int(1)

Несовместимость между расширениями Memcache и расширениями memcached при чтении и записи данных массива обусловлена тем фактом, что memcached определяет идентификаторы различных типов данных для детального разделения типов данных и что идентификаторы массивов несовместимы с идентификаторами массивов, определенных memcached. Чтобы гарантировать, что данные, записанные непосредственно расширениями Memcache и расширениями memcached, могут быть прочитаны друг от друга, MC может быть записан только в строковом формате. После этого исследования я также понял, что многие memcached лучше, чем memcached. Я верю, что с ростом популярности php 7 memcached будет устранен историей.

Воспроизведено от: Автора: Хорошо, адрес этой статьи: [http://www.akayzhang.com/arti…