memcache get value with random result - memcached

I try to get value with a key without any updated but everytime get different value.
I am not sure it's bug of memcache or php.
environment: php7.4.30 & memcache 4.0.5.2
code:
$oMemcache=new Memcache();
$oMemcache->connect($ip,$port);
$a=$oMemcache->get($key);//string(1) '1'
$b=$oMemcache->get($key);//string(0) ''
$c=$oMemcache->get($key);//string(1) '1'

Related

Memcached lru_crawler metadump doesn't returns END as response

We are currently working on getting all the keys in Memcached through:
lru_crawler metadump all
For this implementation, we are expecting END or OK at the end of result.
But Memcached doesn't return any response code after the end of data. It just simply returns the metadata.
lru_crawler metadump 1
key=key exp=-1 la=1588598718 cas=1 fetch=no cls=1 size=80
We are using Memcached version 1.4.33.
Is there any configuration that we need to set up for this to return a response code at the end (or) Is there any way that we can find the end of metadump result other than END or OK?
Thanks in advance.
Seems it is a known issue with the Memcahed
https://github.com/memcached/memcached/issues/667
(came across this post when researching a project I'm working on)
It is no longer an issue in current memcache implementations - I'm using 1.5.6 and get 'END'. However it is my experience that this does not always return the full list. I suspect that may be due the order of items in the LRU list changing while command is running (I get 99-100% of the keys when the server is getting hammered).

memcached set not stored

The following step has followed:
telnet localhost 11211
set Test 0 100 10
get Test
CLIENT_ERROR bad data chunk
ERROR
set amit 2 2 2
get amit
CLIENT_ERROR bad data chunk
ERROR
In my case I was providing the value but the bytes were not exactly what I was mentioning in the set command, for the format of the command is:
set KEY META_DATA EXPIRY_TIME LENGTH_IN_BYTES
so for those who were just copy pasting the command without knowing as to why is it not storing the key and came here for the answer, this might help:
You need to provide the value of exactly the same bytes which you have mentioned in the last parameter of the set command
the following won't work:
also the following won't:
So when you enter the value it has to be exactly the same bytes, like this:
Although you do not ask a specific question, i presume you want to store a value.
You could test with the default example from the Memcached manual.
You define that you want to store a key, but don't specify a value.
The following example specifies that you want to save a key "tutorialspoint", no flags, timeout of 900 and reserve 9 bytes for a value. Those 9 bytes are specified in the next line: "memcached". In your example i don't see a value.
set tutorialspoint 0 900 9
memcached
STORED
get tutorialspoint
VALUE tutorialspoint 0 9
memcached
END
‘set Test 0 100 10’, then enter a value which the length is equal to 10。
the set command takes 4 arguments:
key - this is an arbitrary key you'll later use to retrieve the value
flag - use 0 for no flags
ttl - time to live in seconds. this is how long memcache will hold your value.
size - in bytes. Byte count of your value.
In my case I was neglecting to calculate the number of bytes and that was why I kept getting the "client error bad data chunk" error

Grafana: No value to text mapping

Like you can see in the following screenshot I am trying to map "no value" to text. What I want to achieve is that in the case of "no value" the text "offline" gets displayed. My guess is that "no value" is not the right parameter to map with, but I have no idea whats the right one. I also tryed NaN which doesnt work to.
I would be really happy if someone can point me to the right value here!
Try null instead of no value.
Also, for your 2nd mapping, you could use range to text. You could use range to text for both your mappings actually..
null - null => offline
1 - 1000 => online
You might need to save dashboard and refresh it to see changes. It did not update for me without a refresh (using an older version though).

Inconsistencies in accessing auto index

I've been playing around with Neo4j auto indexing and I'm quite confused...
What I'm using:
neo4j-community-1.8.M05
ruby1.9.3p194
The following code is also at https://github.com/LouisSayers/Neo4jChallenges
My intention is to create nodes which have unique 'uuid' values (generated by me). To ensure that they are unique, my thinking was to check against an index, and if the uuid value already exists, then I'd generate a new uuid value.
What I see is that for one of my uuids ('blahblahuuid') this works, but for the other it doesn't... and I don't know why (check in the Neo4j Monitoring tool console).
If you try the code below on a clean install of neo4j on ruby1.9.3 (no changes to properties etc) then hopefully you'll see the behaviour that I'm seeing!
Here's my code:
Gemfile:
source "http://rubygems.org"
source "http://gems.rubyforge.org"
source "http://gemcutter.org"
#gem install bundler -v 1.2.0.pre --pre
ruby '1.9.3'
gem 'bundler', '1.2.0.pre'
gem 'neography', :git => 'https://github.com/maxdemarzi/neography'
test.rb:
require "rubygems"
require "bundler"
require 'digest/sha1'
require 'securerandom'
Bundler.setup(:default)
require 'neography'
$neo = Neography::Rest.new("http://localhost:7474")
$neo.create_node_index("node_auto_index")
$neo.set_node_auto_index_status(true)
$neo.execute_script("g.clear()")
def generate_uuid(deviceUUID)
uuid = Digest::SHA1.base64digest deviceUUID
existing_node_with_uuid = $neo.get_node_auto_index('uuid', uuid)
until existing_node_with_uuid.nil?
uuid = Digest::SHA1.base64digest (deviceUUID.to_s + SecureRandom.base64(8))
existing_node_with_uuid = $neo.get_node_auto_index('uuid', uuid)
end
uuid
end
def generate_node(deviceUUID)
uuid = generate_uuid(deviceUUID)
secret = SecureRandom.base64(256)
currentTime = DateTime.now
$neo.create_node("uuid" => uuid, "deviceUUID" => deviceUUID,
"secret" => secret, "currentTime" => currentTime)
end
generate_node('blahblahuuid')
generate_node('blahblahuuid')
generate_node('4edb096b479588f6')
generate_node('4edb096b479588f6')
To run the code:
ruby test.rb
Listing results in the neo4j console:
start all = node(*)
return all;
# UPDATE
I figured out what was going wrong - firstly I didn't index uuid properly, I needed to add:
$neo.add_node_auto_index_property("uuid")
and as Max pointed out, I had a '/' in my uuid.
Also as pointed out by Russell Duhon (https://groups.google.com/forum/?fromgroups#!topic/neo4j/KyW0s5p5-fM)
I should have just used a uuid library - which is what I'm doing now (using the uuid gem - https://github.com/assaf/uuid/) and then I avoid having to check whether the same uuid exists - as the uuid should be unique.
I am also encoding all of my parameters that I pass through neography - as there is a chance that some of them may contain slashes, and '?&=' symbols which could interfere with the rest url!
Thank you Max and Russell for your help!
It is doing:
existing_node_with_uuid = $neo.get_node_auto_index('uuid', '7sZfZnCgz4sL/TkE4tPqb5+GgF0=')
Which is sending a get request to:
/db/data/index/node/node_auto_index/uuid/7sZfZnCgz4sL/TkE4tPqb5+GgF0=
I think that "/" is making a mess of things.

Does setting a memcached key that already exists refresh the expiration time?

Let's say I have the following code:
Memcached->set('key', 'value', 60); (expire in one minute)
while (1) {
sleep 1 second;
data = Memcached->get('key');
// update data
Memcached->set('key', data, 60);
}
After 60 iterations of the loop, will the key expire and when reading it I'll get a NULL? Or will the continuous setting keep pushing the expiration time each time to 1 minute after the last Set?
The documentation mentions this, and I've tested this in different contexts and I'm pretty sure I got different results.
Ok, found my answer by experimentation in the end...
It turns out "Set" does extend the expiration, it's basically the same as deleting the item and Setting it again with a new expiration.
However, Increment doesn't extend the expiration. If you increment a key, it keeps the original expiration time it had when you Set it in the first place.
If you simply want to extend the expiration time for a particular key instead of essentially resetting the data each time, you can just use Memcached::touch
With the caveat that you must have binary protocol enabled according to the comment on the above page.
$memcached = new Memcached();
$memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$memcached->touch('key', 120);
The set doesn't care whatsoever about what may have been there, and can't assume that it even came from the same application.
What all did you test and what kinds of results did you get? Memcached never guarantees to return a value, so if you saw it go missing, it's quite possible to construct a test that would lose that regardless of expiration.
The best documentation source is the Memcached protocol description
First, the client sends a command line which looks like this:
<command name> <key> <flags> <exptime> <bytes> [noreply]\r\n
- <command name> is "set", "add", "replace", "append" or "prepend"
As you may see, each of the commands above have the exptime field which is mandatory.
So, yes - it will update expiration time. Moreover, memcached creates new item with its own key / flags / expiration / value and replaces the old one with it.
If your goal is to simply extends the expiration time, use the command touch, that was created to set a new expiration time for a key.
See https://manned.org/memctouch or http://docs.libmemcached.org/bin/memtouch.html
Debian package: libmemcached-tools
From the shell: man memctouch
other distros use "memtouch" as the name of the command line tool
+1 Link from memcached protocol, as a manual reference:
https://github.com/memcached/memcached/blob/master/doc/protocol.txt#L318
Example:
memctouch --servers=localhost --expire=60 $key
Where $key is your 'key', this will set the expire time to 60 seconds, as in your example, but without having to make a "get" AND re-set the key. What if your 'key' is not set yet and your 'get' doesn't return some data?