PHP - memcached copy key/value from one server to another - php

I am curious is there a possibility in PHP to copy key/value from one memcached server directly to another using Memcached module?
Is connections to 2 different servers at one time allowed at all?
Thanks in advance!

The following would allow you to connect to two different Memcached servers and set the same data on both:
//Server A
$memcacheA = new Memcache;
$memcacheA->connect(216.239.51.99, 11211) or die ("Could not connect");
//Server B
$memcacheB = new Memcache;
$memcacheB->connect(115.239.51.98, 11211) or die ("Could not connect");
//Getting data from your database.
$myVal = $customObj->getSomethingFromDB();
//If data not stored on Server A
if($memcacheA->get('var_key') === false){
//Store it on Server A
$memcacheA->set('var_key', $myVar, MEMCACHE_COMPRESSED, 50);
}
//If data not stored on Server B
if($memcacheB->get('var_key') === false){
//Store it on Server B
$memcacheB->set('var_key', $myVar, MEMCACHE_COMPRESSED, 50);
}
Depending on your use case, this may or may not be a good solution. Depends on what your situation is and what you're attempting to achieve.

Related

Make persistent connection in php socket to avoid too many apache instances

I have a page that contains a picture. The picture should refresh every second. I have a socket.php file that creates a link to a c++ program and asks for a picture and then put it as output. I have a js code that asks socket.php for an image every second.
So
every second my js code in clients browser, asks socket.php on my server to send the user a new picture and socket.php asks my c++ code for a picture, receive the picture and pass it to the client browser.
every thing is ok.
but when I change the interval from 1 second to 50 miliseconds, the number of "apache2" processes on my server goes really up. I mean about 200 apache2 processes and this uses too much ram memory on my server.
My question is: what should I do to make a have a persistent connection between php and c++ , so for every query from user, a new connection doesn't create? Does a persistent connection help to avoid this number of apache processes?
This is my socket.php file:
if(isset($_GET['message']))
$message = $_GET['message'];
else $message = "-1";
$host = "127.0.0.1";
$port = 12345;
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
$result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
$b= '';
$buf = '';
while(true)
{
$bytes = socket_recv($socket, $buf, 2048, 0);
if($bytes==0) break;
$b .= $buf;
}
$im = imagecreatefromstring($b);
header('Content-Type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
This is my js code:
function updateImage()
{
if(!isPaused)
{
if(newImage.complete) {
document.getElementById("myimg").src = newImage.src;
newImage = new Image();
newImage.src = "socket.php?message=0&image" + count++ + ".jpg";
}
setTimeout(updateImage, 50);
}
}
60 calls in a min it's nothing and 200 too. I think problem is you don't close socket.
the best approach is make you c++ update mysql DB every second and page should ask for updated image from DB, like this you will gain flexibility.
At that point you also can do cashing of the image
Also you can attach as much image users as you want without opening the new sockets and without C++ application calling.
As far as I can tell, one really cannot persist a connection from an Apache instance of PHP (e.g. mod_php) to another service, except for database connections (e.g. all of those supported by PDO). #volkinc's link to how PHP executes is a pretty good example which illustrates where such a persistent link would have to cached/stored by PHP, but is not.

Memcached Performance

I feel the speed of Memcached in my website is slower than Mysql queries. Please see the screenshot of performance of my website I got from New Relic.
I don't know how to optimize memcached in my CentOS server. Please see the configuration and performance screenshots of Memcached. I feel the number of Total Connections is high.
Please see Live Stats below
The following is how I use Memcached in my website
<?php
class dataCache {
function setMemData($key, $var, $flag = false, $expire = 36000) {
global $memcache;
if (!$memcache) {
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die("Could not connect");
}
if ($result = $memcache->set($key, $var, $flag, time() + $expire)) {
return TRUE;
} else {
return FALSE;
}
}
function getMemData($key) {
global $memcache;
if (!$memcache) {
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die("Could not connect");
}
if ($data = $memcache->get($key)) {
return $data;
} else {
return FALSE;
}
}
function delMemData($key) {
global $memcache;
if (!$memcache) {
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die("Could not connect");
}
if ($result = $memcache->delete($key)) {
return TRUE;
} else {
return FALSE;
}
}
}
And at the end of each PHP page, I use the following way to close the connection
if(isset($memcache)){
$memcache->close();
}
Do I need more memories for this server? How to reduce the number of connections? Any suggestions to improve the performance?
--------------EDIT------------------------
As the comments mentioned, the current connections are 9. The total connections are 671731. The number of connections might be not a problem.
Here are a few ways to make this go faster.
Your total connections are actually how many connections have been created to memcached.
First, use the memcached php extension NOT the memcache extension. They are entirely different and the memcache extension is pretty much deprecated to death. Memcached extension uses libmemcached which is incredibly faster and has better features (like binary protocol, better timeouts, udp)
Second, use persistent connections. For your workload these should be entirely sufficient and reduce the cost of constantly reconnecting to memcache.
Third, use multi get/set/delete/etc. If you know you will need 10 memcache keys in your request, ask for all 10 at once. This can give you a big performance increase if you are looping over memcache requests at any point.
Another caveat is that NewRelic is historically BAD at reporting time spent in memcache. It can misreport time spent in php as time spent in memcache due to how the instrument the zend engine.
As for why your memcache and mysql performance are so close, you are most likely running rather simple queries so the time spent on memcache and on mysql are comparable. Memcache is extremely fast but it is also a network hop and that is usually the largest amount of the time spent waiting for memcache. You could try running memcache locally or using APC instead of memcache if you really only have 1 server.

PHP memcache connect

I have a page where few thousands of users can hit a method at the same time . I do have following code where I connect every time . Since this will go to a seperate memcache server will this cause slowdowns is there a way to connect just once and reuse that connection ? Do I have to close connection after every request ?
$primary_connected = $memcache_primary->connect($primary_memcache_server, 11211);
if($primary_connected){
$data = $memcache_primary->get($key);
if ($data != NULL) {
return data;
}
}
else{
/////Get data from database
}
If you are using the PHP memcached class (the one with the d on the end, not memcache) then yes, you can open a persistent connection.
You can pass a persistent ID to the constructor which will open a persistent connection and subsequent instances that use the same persistent ID will use that connection.
$memcached = new Memcached('method_name_or_persistent_identifier');
$memcached->addServer(...);
// use it
Hope that helps.
See Memcached::__construct() for more details.

Memcache + Mysqli Couldn't fetch mysqli_result

I'm trying to add some speed performance to a project I'm working on using memcache. However I'm having a problem with the following
public function sql_query($query){
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$memkey = md5($query);
$get_result = $memcache->get($memkey);
if ($get_result){
return $get_result;
} else {
$q = $this->mysqli->query($query);
$memcache->set($memkey, $q, false, 120) or die ("Failed to save data at the server");
if ($this->mysqli->error){
App::Error($this->mysqli->error);
}
return $q;
}
}
It is certainly putting something into memcached but I get this error when pulling it back out and use it as I would if it wasn't from the cache.
"Warning: mysqli_result::fetch_assoc(): Couldn't fetch mysqli_result"
Am I missing something? I'm sure I've used memcache before in a similar way without any issues.
You can not store all data-types into memcached (and other data-stores), one which most often does not work are resources Docs, for example a database link or a result identifier.
You stored such a value and on another request you pulled it out again. But as the database already is in another state, this resource does not work any longer. You get the error then.
Instead you need to store the result data from the query, that's static data you can put into memcache.

Failed to save data at the server from memcached program

hi i want to know why i cant store multi dimensional(array size is more than 1000)
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
the above s working correctly...
the below one have error...
$memcache->set('key', $sear, false, 60) or die ("Failed to save data at the server");
if the $sear is string or object array then no problem for store data at the server..
but i store multi dimensional array in memcached,,i will get the error is
Failed to save data at the server
thanks and advance
The array you're trying to store is probably too large. Memcache has a limit on the size of a single item. The maximum size per item is 1,048,576 Bytes or 1MB.
Here is another thread regarding this issue...
Can you store a PHP Array in Memcache?

Categories