Darghon Posted June 27, 2011 Share Posted June 27, 2011 Hi, I'm creating a webgame in a self made framework. Right now I'm attempting to make each and every request go as fast as possible, and I've been reading up on caching and have made quite a journey to where I am now. Now my next problem is that during the game, some data gets reloaded every single request, and I want to prevent the server for loading the same data 100's of times / minute during peak moments. So I googled some, and found memcached, redis, semaphores, sharedmemory blocks, ... They all look promising, but what should I use... What I want: I want to be able to get a shared object stack in memory, that every process can access. The objects itself will be saved when changed, but the idea is that the server doesn't need to request the data each time someone refreshes a page, but that it can just retrieve it from a shared memory resource. It would even be fantastic if I were able to provide a wrapper that would react on whatever was available, but that's running ahead of myself. Anyone have experience in setting up a shared data resource in php? and if so, how can I do this? Thx for any and all responses Quote Link to comment https://forums.phpfreaks.com/topic/240522-sharing-high-usage-objects-between-sessions/ Share on other sites More sharing options...
QuickOldCar Posted June 27, 2011 Share Posted June 27, 2011 memcached is most likely your best bet. http://memcached.org/ Even if created arrays of text and saved them as xml, you would have bottlenecks in disk i/o, not to mention the size it would grow to. You could look into query cache. http://dev.mysql.com/doc/refman/5.6/en/query-cache.html Can also do page caching per unique url if the content is the same data, just don't cache user data. http://devgrow.com/simple-cache-class/ http://files.zend.com/help/Zend-Server/zend_page_cache_-_php_api.htm http://php.dzone.com/news/php-caching-pages-with-output- Quote Link to comment https://forums.phpfreaks.com/topic/240522-sharing-high-usage-objects-between-sessions/#findComment-1235445 Share on other sites More sharing options...
Darghon Posted June 27, 2011 Author Share Posted June 27, 2011 The concept that I had in mind was that I made a block of data, that in case it got full, would kick the least used data. This way the size would remain very limited, (or within control), and everything that needed to be loaded frequently would be "ready-to-use". The system uses nothing but objects, and the global idea is that in case a rather large portion of memory could be used for this, that the system would only get ID's from the database, and if the object ID wasn't found in the cache, that then, and only then the data would come from the database, and otherwise just retrieve it from global repository. not sure if my explenation is clear though... Quote Link to comment https://forums.phpfreaks.com/topic/240522-sharing-high-usage-objects-between-sessions/#findComment-1235508 Share on other sites More sharing options...
Darghon Posted June 28, 2011 Author Share Posted June 28, 2011 I've been playing around with memcached, installed a localhost memcache server, and implemented my registry to save all objects in memcache. Now I don't notice any load increases, at all. which is pretty disappointing, so I was wondering if maybe I was doing it wrong... a test page that loads 24 objects and 7 finders loads in 0.3seconds with the registry (2 objects arrays), and in 0.3seconds with the memcache server (average over 1000 loads) My "MemoryHandler" class handles 2 cases, first case if when you use memcache, 2nd is when you can't. The class is a singleton, so only 1 instance of it will be available at any time. This class is build and maintained by a static call, so you will never declare it yourself Functions that my objects use are the following: ObjectCollector::Memory()->retrieve($class,(option)$id); ObjectCollector::Memory()->register($object); There are 2 types of objects that can be "cached" this way, a businesslayer object (containing data), and a finder (containing database connection data, and sql statements) The following is the code for the memory handler, and if anyone sees anything strange, or wrong, do tell... cause this way, it isn't decreasing my load time... <?php class MemoryHandler{ /** * Mode that specifies that memcached server should be used (if possible) */ const MODE_MEMCACHE = 1; /** * Mode that specifies that the systeem needs to keep a collection during load */ const MODE_REGISTRY = 0; protected $timeout = 30; protected $objectcollection = null; protected $findercollection = null; protected $memcache = null; protected $mode = self::MODE_MEMCACHE; protected $connected = false; public function __construct(){} /** * Public function that registers the added connection data to the memcache object */ public function connect($host, $port = 11211){ return $this->addServer($server,$port); } public function addServers(array $server_array){ foreach($server_array as $server){ if(is_array($server)){ $this->addServer($server["host"],$server["port"]); } else{ $this->addServer($server); } } } public function addServer($host, $port = 11211){ if($this->mode != self::MODE_MEMCACHE) return false; if($this->memcache->addServer($host,$port) === true){ $this->connected = true; return true; } else{ return false; } } public function & register($object){ if($this->mode == self::MODE_MEMCACHE) return $this->register_memory($object); if($this->mode == self::MODE_REGISTRY) return $this->register_registry($object); } private function & register_memory($object){ $class = get_class($object); $id = is_subclass_of($object,'Finder') ? null : $object->getID(); $this->memcache->set($this->generateKey($class,$id),$object,0,$this->timeout); $obj = $this->memcache->get($this->generateKey($class,$id)); return $obj; } private function & register_registry($object){ if(is_subclass_of($object,'Finder') === true){ if(!array_key_exists($object->tag(),$this->findercollection)){ $this->findercollection[$object->tag()] = $object; } return $this->findercollection[$object->tag()]; } else{ if(array_key_exists($object->tag(),$this->objectcollection)){ if(!array_key_exists($object->getID(),$this->objectcollection[$object->tag()])){ $this->objectcollection[$object->tag()][$object->getID()] = $object; } } else{ //If no previous object of this type is stored, the collection is created, and the object is added $this->objectcollection[$object->tag()] = array( $object->getID() => $object ); } return $this->objectcollection[$object->tag()][$object->getID()]; } } public function & retrieve($class, $id = null){ if($this->mode == self::MODE_MEMCACHE) return $this->retrieve_memory($class,$id); if($this->mode == self::MODE_REGISTRY) return $this->retrieve_registry($class,$id); } private function & retrieve_registry($class, $id = null){ if(is_subclass_of($class, 'Finder')){ if(!array_key_exists($class,$this->findercollection)){ $finder = new $class; $this->findercollection[$class] =& $finder; } return $this->findercollection[$class]; } else{ //Set a default variable to be returned if needed (object expected in referenced return) $objdef = false; //If Business object type is already set in the objectCollection Array if(array_key_exists($class,$this->objectcollection)){ //Check if the collection has the object with the requested id if(array_key_exists($id,$this->objectcollection[$class])){ return $this->objectcollection[$class][$id]; } return $objdef; } else{ return $objdef; } } } private function & retrieve_memory($class,$id = null){ if(is_subclass_of($class, 'Finder')){ $obj = $this->memcache->get($this->generateKey($class)); if($obj === false){ return $this->register(new $class); } return $obj; } else{ $obj = $this->memcache->get($this->generateKey($class,$id)); return $obj; } } public function getStats(){ if($this->memcache !== null){ $return = $this->memcache->getStats(); $this->memcache->flush(); return $return; } else{ return 'memcache not loaded'; } } /** * Public function that sets the mode of the memory handler * @param Integer $mode */ public function setMode($mode = self::MODE_MEMCACHE){ $this->mode = $mode; if($this->mode == self::MODE_MEMCACHE){ $this->memcache = new Memcache; } else{ $this->memcache = null; $this->objectcollection = array(); $this->findercollection = array(); } } /** * Public function that retrieves the mode of the memory handler * @return Integer $mode; */ public function getMode(){ return $this->mode; } private function generateKey($class, $id = null){ if($id !== null){ return Tools::encrypt($class.$id); } else{ return Tools::encrypt($class); } } public function __destroy(){ foreach($this as $key => $var){ unset($this->$key); } unset($this); } } Quote Link to comment https://forums.phpfreaks.com/topic/240522-sharing-high-usage-objects-between-sessions/#findComment-1235855 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.