Memcache + PHP - Why data is not expiring? - php

I have a simple example where I set a value for 5 seconds. The problem is that after 5 seconds; I still get back a value when I expected 'false'.
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$memcache->set('foo', 'bar', 0, 5); // 5 seconds expiry
var_dump($memcache->get('foo')); // bar
sleep(10);
var_dump($memcache->get('foo')); // still shows bar
Here is the memcache server version
Server's version: 1.4.13

Late to the game, but in your code it looks like you are passing "0" for the expiration (not "5"), which translates to "never expire" Specifically:
$memcache->set('foo', 'bar', 0, 5); // 5 seconds expiry
Should be:
$memcache->set('foo', 'bar', 5); // 5 seconds expiry
Unless I'm misunderstanding the PHP documentation located here, which shows that the set command takes three parameters:
public bool Memcached::set ( string $key , mixed $value [, int $expiration ] )
Edit: Whoops, I see that you're using the Memcache extension and not Memcached, which does have four parmaters. Perhaps try using the MEMCACHE_COMPRESSED constant instead of 0 to see if it works:
$memcache->set('foo', 'bar', MEMCACHE_COMPRESSED, 5); // 5 seconds expiry

There was a bug in the memcached server including version 1.4.13 through at least 1.4.14 that, once the memcached server had been running for some time, it would sometimes get into a mode where it would fail to properly expire values.
Restarting the service fixed it for me, and I'm hopeful that the newer versions fix it more permanently.

As the code looks fine - the next chain down the line is to look at either your version of the memcache PHP extension not working, or memcached server itself.
This get a but tricky. Easiest is to rule out memcached server first. (There's a php interface you can install - but that won't help you work outwhich bit.) So...
In terminal (or command window in Windows) type
telnet localhost 11211
(Note - telnet client is not installed in Windows by default - go to "control panel", "turn windows features on or off" and add from there.)
This gives you access to memcached.
Then type
stats items
which lists the memory items in memcached.
Hopefully you've only got one slab, so note its number and type
stats cachedump [Number] 0
And this will list what's recorded in cache.
If this still shows "bar" (in encoded format) then it's memcached server that's not working - upgrade for a newer version.
If this doesn't show "bar" (or, preferably, the item just doesn't exist - you get ERROR instead) then it'll be the memcache extension to PHP that's not working. Again, check your version of that.
When done, type
quit
Alternative is to check out "memcached" (php extension) and rewrite your PHP code with those classes. It's newer. If that still fails, it's definately memcached server; if that works that it was the php memcache extension.

Related

Get Server CPU Type with php

I'm trying to determine the CPU type of the server my PHP is running on. I'm not need the CPU usage.
The determination of the CPU type should work independently of the system (Win/Linux..).
The solutions I found evaluate the /proc/cpuinfo file.
This solution only works for linux systems and then only if the rights for access are available.
Example: PHP Script - Get Server Processor
My approach was to use php function php_uname with parameter 'm'.
<?php
var_dump(php_uname('m'));
//string(6) "x86_64"
Unfortunately, this solution fails on some host systems.
An answer is then generated there which is identical to the parameter 'a'.
Example:
'Linux localhost 3.10.0-1160.36.2.el7.x86_64 #1 SMP'
The solution should only require PHP and must be able to run without additional installations. I am thankful for all hints.
Try phpinfo(). phpinfo(int $flags = INFO_ALL): bool.
Outputs a large amount of information about the current state of PHP.
This includes information about PHP compilation options and
extensions, the PHP version, server information and environment
I don't know if it's a bad installation or a PHP bug when php_uname('m') returns an incorrect response on some host systems. These are all GNU/Linux systems. Access to /proc/cpuinfo is forbidden. However, I can run the uname command there. This is my current solution:
function getCPU(){
$name = php_uname('m');
//workaround bug
if(strlen($name) > 20 AND stripos($name,'linux') !== false){
$name = `uname -m`;
}
return trim($name);
}
The function returns a short string like "AMD64", "x86_64" or "aarch64" on success.
Demo on 3v4l.org.

Share variables between python & php

I have a script in python receiving continuously data from sensors.
I need to publish the last data at request on a webpage using php.
Apache, php and python are all on the same linux install (actually on an raspberry).
I'm not interested in storing previous data and I'm a bit concerned about data corruption on writing on SD. I would prefer to reduce complexity and increase speed refresh (avoid sql).
Could a text file written in ramfs / tmpfs solve the problem? or there is a method to share memory like memcache to share also global variables?
Any practical example or howto will be really well-accepted.
I think you may try System V shared memory.
As example:
In Python side:
python -m pip install sysv_ipc
then somewhere in the python script:
import sysv_ipc
...
KEY=20171220
sysv_memory=sysv_ipc.SharedMemory(KEY, sysv_ipc.IPC_CREAT, 0666, 256)
...
sysv_memory.write('1234'+'\0')
Then in the PHP side:
$SHARED_MEMORY_KEY = 20171220;
...
$shmId = shmop_open($SHARED_MEMORY_KEY, 'a', 0666, 256);
...
$test_string = shmop_read($shmId, 0, 0);
I can get the $test_string as '1234' successfully in PHP.
Here is a solution using memcached that works on Raspbian 10 (buster), PHP 7.3.19, and Python 3.7.3:
1. Install memcached
apt-get install memcached php-memcached
pip install pymemcache
These commands install memchached server and client modules for PHP and Python.
2. PHP code
$m = new Memcached();
// connect
$m->addServer('127.0.0.1', 11211);
// get a value
$value = $m->get('key');
// set a value
$m->set('key', 'value');
// clean up
$m->quit();
3. Python code
from pymemcache.client import base
# connect
m = base.Client(('127.0.0.1', 11211))
# get a value
value = m.get('key')
# set a value
m.set('key', 'value')
# clean up
m.close()
Note:
I used default memcached settings here. If you need to change them edit sudo nano /etc/memcached.conf and restart the daemon: sudo /etc/init.d/memcached restart.
You can use any interoperable format like json or msgpack.
Whenever you generate data in python, add it to a caching layer like memcache/redis using json format ( and preferably a gzip compressed version), then your PHP script can unserialize the json data and display it in the app.
Clearly memcache as a means to share data different application will work.
You will not have any corrupted data for sure as all the memcache operation are atomic. memcache atomic discussion could be useful.
On memcached's FAQ:
Is memcached atomic? Aside from any bugs you may come across, yes all commands are internally atomic. Issuing multiple sets at the same time has no ill effect, aside from the last one in being the one that sticks.
Note: Running memcache service might consume considerable amount of memory.
Hope it helps!

Apache Connection Time Out

I have a report that generates an array of data from MySQL server by using looping through PHP code (Laravel framework). However, the maximum that the server can handle is an array with 400 row, and each row contains 61 child value in it.
[
[1, ...,61], // row 1
.
.
.
[1,....,61] // row 400
]
Each value is calculated from running a loop that retrieves data from MySQL server.
There is a no load balancer.
I tried to increase max_execution_time = 600 (10 minutes), but it still show the connection time out problem. Any thoughts? Thanks,
Connection Timed Out
Description: Connection Timed Out
Server version: Apache/2.4.7 (Ubuntu) - PHP 5.6
Would need more info for a definitive answer...
What is the Apache/httpd version (there have been some bugs that relate to this)?
Is there a firewall or load balancer in the mix?
If you are sure it is still a timeout error and not say memory, then it is probably httpd's TimeOut directive. It defaults to 300 seconds.
If still stuck paste the exact error you are seeing.
My PHP version was 5.6. After upgrading to PHP7, my application speed was increased significantly. Everything works fine now.

AjaXplorer [written in PHP] is too slow on IIS

I've installed AjaXplorer (very nice web file explorer), written in PHP, on my IIS (Windows Server 2008 SP2 x64). It works too slow for me.
What can be the cause? Are there some settings in php.ini? Or, maybe, something is wrong with IIS?
I use 32-bit PHP, php-cgi.exe as interpreter.
Regards,
First off, CGI will always be slow. It needs to boot the entire PHP runtime for each request. Try using FastCGI (If you're using IIS 7, or if you're using IIS 6)...
After that, try to see why it's slow. Is it because the PHP script takes a long time to execute (meaning it's a code issue), or is it because of a server config. To test, modify this into the start of the entrance point of the PHP program (index.php):
define(START_TIME_CUSTOM, microtime(true));
function onEndTimeCompute() {
$timeTaken = microtime(true) - START_TIME_CUSTOM;
echo "Completed In: ".number_format($timeTaken, 4)." Seconds\n";
}
register_shutdown_function('onEndTimeCompute');
That write Completed in n Seconds to the end of the generated output (even if die() is called). It may cause some issues if Ajax calls are expected to return JSON, so don't do it as a rule, just for trying to figure out what's going on.
So, if the total request takes 1 second, yet you see Completed in 0.004 Seconds, you know that the PHP code itself is not the issue (it's either in the setup of the interpreter by CGI, or somewhere else in IIS)...
That should at least show you where the problem is...

PHP pecl/memcached extension slow when setting option for consistent hashing

Using the newer PHP pecl/memcached extension. Calls to Memcached::setOption() like;
$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
are costing between 150 to 500ms - just in making the call to setOption() and as we're not using persistent connections but rather doing this on every request, it hurts.
Delving deeper, setting Memcached::OPT_DISTRIBUTION to Memcached::DISTRIBUTION_CONSISTENT ends up calling update_continuum() in libmemcached which appears to be fairly intensive, although we're only passing a list of 15 memcached servers in, so somewhat surprising to see it take between 150 to 500ms to rebuild the continuum data structure.
Could it be setting this option is only suitable for persistent connections, where it's called only once while making the initial connection? Or is this a bug libmemcached?
Using the newer pecl/memcached extension 1.0.1 with libmemcached 0.38
Thanks.
libmemcached 0.38 is fairly old at this point. So is pecl/memcached 1.0.1. Could you try pecl/memcached 2.0.0b1 release from github?
Same issue with pecl/memcached 2.2.0 (latest from PECL as of writing). The only solution for me was to switch from DISTRIBUTION_CONSISTENT to:
$memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$memcached->setOption(Memcached::OPT_REMOVE_FAILED_SERVERS, true);
It seems to work fine:
var_dump($memcached->getServerByKey($key)['host']);
// string '192.168.56.1' (length=12) <== dead host
$memcached->set($key, $result, 3600);
var_dump($memcached->getServerByKey($key)['host']);
// string '127.0.0.1' (length=9) <== working host
var_dump($memcached->getLastErrorMessage());
// string 'SUCCESS' (length=7)

Categories