Не могу добиться атомарности при сохранении данных

webwin

Новичок
Здравствуйте.
Нужно сохранить объект со структурой разделов сайта в memcache
Он занимает больше 1М и разбивается на пару частей. Использую блокировку для атомарности, но иногда данные все не считываются и соответственно некоторые разделы на сайте не доступны.
Возможно, не правильно использую блокировку для сохранения?

PHP:
        $lock = false;
		while ($lock == false) {
			$lock = $memcache->add($sunsite[domain].'.allpagesnew_'.$langid.'::lock',1,0,15);
			if (!$lock)
				usleep(100);   
		}
		if ($memcache->set($sunsite[domain].'.allpagesnew_'.$langid, $allpages, false)):
			write_childs($allpages_all, $langid);
			$allpages->_all = $allpages_all;
			$allpages->AfterLoad($allpages);
		endif;
		$memcache->delete($sunsite[domain].'.allpagesnew_'.$langid.'::lock');
 

fixxxer

К.О.
Партнер клуба
Ну а чтение то где?

И бесконечный цикл тут опасный, сам себя задосишь если что :)
 

webwin

Новичок
PHP:
global $memcache, $sunsite, $db;
	$db->query("SELECT val FROM  pages_dump_conf WHERE id=$langid");
	if ($db->next_record())
	{
		$i = $db->Record['val'];      
		$allpages_all = array();	
		while ($i>=0) 
		{
			$dump = $memcache->get($sunsite[domain].'.allpagesnew_'.$langid.'_'.$i);
			if (is_array($dump))
			{
				$allpages_all = $allpages_all + $dump;
			}
			else 
			{
				//
			}
			$i--;
		}
		return $allpages_all; 
	}
Цикл не бесконечный, блокировка через 15 секунд истекает
 

MiksIr

miksir@home:~$
Кладите с ключами <blabla>_<index>, где index - счетчик, который там же в мемкеше храните. На обновлении кладете данные с новым index и потом меняете его. Как-то так делал бы....
Минус - будет лишнее чтение на получении информации, имхо, не критично. Еще минут - какое-то время будут и старые и новые данные в мемкеше, т.е. занимать место.. критичность вам виднее.
Можно просто тупо пересобрать мемкеш с большим размером slab-а.
 

fixxxer

К.О.
Партнер клуба
webwin
Нельзя рассчитывать, что в мемкеше данные будут. Всегда возможно вытеснение. (Хотя может я просто не понял, код странноват)

MiksIr
Зачем так сложно? Достаточно в данных хранить массив ( data, version ) и отдельно ключик с версией, не совпадает - значит expired. Читаются оба сразу мультигетом. Блокировка тут вообще не нужна, она нужна чтобы не делать в момент expiration-а кучу тяжелых запросов к базе, а этот момент автор вообще судя по приведенному коду не считает нужным решать (в общем-то, и не всегда его надо решать - если запросы быстрые а число запросов в секунду малое, то пофиг).
 

MiksIr

miksir@home:~$
Понятно, что код заполнения, если данных нет, должен быть. Но если у него несколько мегабайт данных, все же обновление методом запихивания новых данных и переключения на них выглядит более привлекательно. Именно из-за отсутствия в этом случае гонки. В принципе ничего не мешает совместить эти способы, если мешать версию в ключ.
 

fixxxer

К.О.
Партнер клуба
ну вообще при мегабайтах да, наверное ты прав

но мегабайты я бы вообще, кстати, кэшировал локально. как-то дофига по сети гонять то...
 
Сверху