Distributed memory-based Cache service Memcached
I. Introduction to memcached
Memcached is a distributed memory-based Cache Server. We generally use memcached to reduce database loads and improve program response speed.
Memcahched uses key-value to store data and serialize the object to binary for transmission over the network.
Ii. Installation in Linux
Memcached is based on the libevent library. Therefore, you must first install libevent and then install memcached. The main steps are as follows:
Tar-zxvf memcached-1.4.25.tar.gz
Cd
./Configure
Make
Make install
After the installation, start the memcached service./memcached-d-m 1024-p 10000-u root-P/tmp/memcached. pid
Check whether the service is started: ps-ef | grep 10000
Iii. Working Mechanism of memached
3.1 memcached memory storage
Memcached is a memory-based high-performance cache server. To improve performance, data stored in memcached is stored in the memory storage space built in memcached. Because the data only exists in the memory, restarting the server or operating system will lead to data loss.
Memcached currently uses Slab Allocator to manage memory. Its principle is very simple. According to the agreed block size, the allocated memory is divided into blocks in advance, and divide blocks of the same size into different groups.
When the client has an add or set operation to store data in the cache, memcached selects an appropriate slab based on the size of the added data.
1. memcached divides the memory space into a group of slab
2. Each page contains a group of chunks. The chunk is the place where the data is actually stored, and the chunk size in the same slab is fixed. If the key does not match the chunk, memory will be wasted. But there will be no memory fragments. We can reduce the size difference between each chunk by-f when starting the service, so as to make more reasonable use of the memory.
3. slab of the same chunk size is organized together and called slab_class.
3.2 memcached cache expired
When adding data to the cache, you can specify an expire to indicate the expiration time of the data, measured in seconds. However, because memecached does not release the allocated memory, when we add data to the cache, the memory space may be insufficient. In this case, memecached needs to select an available memory to store our data.
Memcached uses the LRU method to release memory, that is, the minimum memory used recently will be preferentially used to store new data.
Memcached uses a lazy mechanism. When a key expires, it does not immediately release the memory. Instead, it will be deleted only after the next get request arrives, in fact, memcached determines whether a key is invalid in many cases. For example, when we re-set a new data, memcached needs to apply for another item to store our data, it will first determine the request size and then select the appropriate slab to put it in. In this place, it has actually determined whether each item has expired when looping the items in slab, if it expires, use this item directly.
3.3 How to implement distributed memcahced
Generally, distributed systems are distributed on the server, but memcached is not. Because each memcached server does not have a master-slave relationship or communicate with each other, therefore, memcached is distributed on the client.
When we cache a key-value data, the client first determines which server to store the data based on the consistent hash algorithm. The principle of this place is very simple. It maps the hash values of each server node to a circle, maps the hash values of the calculated key to the circle, and searches for the first server clockwise, if the value corresponding to the key is found, it is saved to this server. If the corresponding server is not found clockwise, select the first server to save the value.
When we have a get request next time, we can use the same algorithm to calculate the hash value corresponding to the key to find the server that stores the value.
3.4 two-phase Hash of memcached
When we write data into the cache, memecached first calculates the corresponding hash value based on the key and finds the corresponding server number. This is the first hash, after determining the corresponding server number, memcached finds the corresponding memcached server in the memcached cluster through socket and writes our data to the chunk of the server. This is the second hash. Similarly, when we get data, the first hash uses the same algorithm to calculate the hash value corresponding to the key, and the corresponding server can naturally obtain the cached data.
Note that memecached adopts the consistent hash algorithm instead of the traditional remainder hash.
The consistent Hash algorithm uses a data structure called the consistent Hash ring to map keys to the cache server. Below is a sketch.
The cache server node is placed on the Hash Ring Based on the Hash value of each server node name, and its Hash value is calculated based on the Key value of the data to be cached, search for the server node closest to the Hash value of this Key value clockwise in the Hash ring, map the Key to the server, and save the value.
Iv. JAVA client simple operation implementation
Tool class:
Package com. memcached. util;
Import java. util. Date;
Import java. util. Map;
Import com. danga. MemCached. MemCachedClient;
Import com. danga. MemCached. SockIOPool;
/**
* Encapsulation of the basic operation class of memcached
*
* @ Author tanjie
*
*/
Public class MemcachedUtil {
Private MemcachedUtil (){
}
Private static MemCachedClient memCachedClient = new MemCachedClient ();
Private static MemcachedUtil memcachedUtil = new MemcachedUtil ();
/**
* Set the connection pool with the Cache Server
*/
Static {
String [] servers = {"192.168.8.88: 10000"}; // IP address and port number
// Weight
Integer [] weights = {3 };
// Obtain the Instance Object of the socket connection pool
SockIOPool pool = SockIOPool. getInstance ();
Pool. setServers (servers );
// Set the weights of available cache servers in the connection pool, which correspond to the locations of server arrays one by one
Pool. setWeights (weights );
// Set the initial connection count, minimum, maximum connection count, and maximum processing time.
Pool. setInitConn (5 );
Pool. setMinConn (5 );
Pool. setMaxConn (250 );
Pool. setMaxIdle (1000*60*60*6 );
// Set the sleep time of the main thread
Pool. setMaintSleep (30 );
// Set TCP Parameters and connection timeout
Pool. setNagle (false );
Pool. setSocketTO (3000 );
Pool. setSocketConnectTO (0 );
// Initialize the connection pool
Pool. initialize ();
// Set serialization. Because the Basic java type does not support serialization, set it to true when the cache data type is string, which can speed up processing.
MemCachedClient. setPrimitiveAsString (true );
}
Public Object get (String key ){
Return memCachedClient. get (key );
}
Public static MemcachedUtil getInstance (){
Return memcachedUtil;
}
// If the key does not exist, it is added. If the key exists, it is overwritten.
Public boolean add (String key, Object value ){
Return memCachedClient. add (key, value );
}
Public boolean add (String key, Object value, Date expiryDate ){
Return memCachedClient. add (key, value, expiryDate );
}
// If the key does not exist, an error is returned.
Public boolean replace (String key, Object value ){
Return memCachedClient. replace (key, value );
}
Public boolean replace (String key, Object value, Date expiry ){
Return memCachedClient. replace (key, value, expiry );
}
Public boolean delete (String key ){
Return memCachedClient. delete (key );
}
Public boolean delete (String key, Date expiry ){
Return memCachedClient. delete (key, expiry );
}
Public boolean delete (String key, Integer hashCode, Date expiry ){
Return memCachedClient. delete (key, hashCode, expiry );
}
// If the key exists, it fails.
Public boolean set (String key, Object value ){
Return memCachedClient. set (key, value );
}
Public boolean set (String key, Object value, Integer hashCode ){
Return memCachedClient. set (key, value, hashCode );
}
// Cache count
Public boolean storeCounter (String key, long value ){
Return memCachedClient. storeCounter (key, value );
}
Public long incr (String key, long value ){
Return memCachedClient. incr (key, value );
}
// Obtain Objects Based on Multiple keys
Public Map <String, Object> getObjects (String [] keys ){
Return memCachedClient. getMulti (keys );
}
// Clear the object
Public boolean flush (){
Return memCachedClient. flushAll ();
}
// Clears the cache objects. servers indicates which machines are cleared in batch.
Public boolean flushBaseTime (String [] servers ){
Return memCachedClient. flushAll (servers );
}
// Obtain the server status
Public Map <String, Map <String, String> getStats (){
Return memCachedClient. stats ();
}
// Obtain the number of items in each slab
Public Map <String, Map <String, String> getStatsItem (){
Return memCachedClient. statsItems ();
}
}
Entity class:
Package com. memcached. vo;
Import java. io. Serializable;
Public class User implements Serializable {
Private static final long serialVersionUID = 1L;
Private String userId;
Private String userName;
Private String adder;
Public String getUserId (){
Return userId;
}
Public void setUserId (String userId ){
This. userId = userId;
}
Public String getUserName (){
Return userName;
}
Public void setUserName (String userName ){
This. userName = userName;
}
Public String getAdder (){
Return adder;
}
Public void setAdder (String adder ){
This. adder = adder;
}
}
The results are as follows:
Test ():
Get data from the cache: memcached
123
Zhang San
Chongqing
TestDelete ():
Get data from the cache: memcached
Obtain data from the cache again: null
TestReplace ():
Get data from the cache: memcached
Get user: 123 from the cache for the first time
Obtain data from the cache again: replaceId
TestGetStats ():
Ip: 10000
Key: items: 4: evicted_nonzero, value: 0
Key: items: 1: evicted_unfetched, value: 0
Key: items: 1: evicted_time, value: 0
Key: items: 1: expired_unfetched, value: 0
Key: items: 4: tailrepairs, value: 0
Key: items: 1: number, value: 1
Key: items: 4: crawler_items_checked, value: 0
Key: items: 1: lrutail_reflocked, value: 0
Key: items: 1: reclaimed, value: 0
Key: items: 4: crawler_reclaimed, value: 0
Key: items: 1: evicted_nonzero, value: 0
Key: items: 4: outofmemory, value: 0
Key: items: 4: age, value: 0
Key: items: 4: evicted, value: 0
Key: items: 1: evicted, value: 0
Key: items: 4: lrutail_reflocked, value: 0
Key: items: 1: tailrepairs, value: 0
Key: items: 4: evicted_time, value: 0
Key: items: 1: age, value: 0
Key: items: 1: crawler_reclaimed, value: 0
Key: items: 4: reclaimed, value: 0
Key: items: 1: outofmemory, value: 0
Key: items: 1: crawler_items_checked, value: 0
Key: items: 4: expired_unfetched, value: 0
Key: items: 4: evicted_unfetched, value: 0
Key: items: 4: number, value: 1
In fact, the methods of the memcached client are similar, but the characteristics of each client are different. This depends on your actual production needs.
V. disadvantages of memcached
After the above analysis, I believe everyone has a preliminary understanding of memcached. memcached is very fast and its performance is sufficient to meet the needs of most applications. However, it also has many improvements:
1: memcache has no identity authentication mechanism, so any machine can connect to the cache server through telnet or other methods.
2: there is no reasonable log function. Once the server crashes due to an error, it is difficult to find the cause of the error.
3: Data in the memory is not safe enough. Server power failure or other factors may cause data loss.
4. When slab processes objects, it will first classify them. For example, objects of KB will be placed in KB space, which will waste a lot of memory space.
Install and configure Memcached source code in CentOS 6.6
Memcached installation and startup script
Performance problems of using Memcached in PHP
Install Memcached in Ubuntu and its command explanation
Install and apply Memcached
Use Nginx + Memcached's small image storage solution
Getting started with Memcached
For details about Memcached, click here
Memcached: click here
This article permanently updates the link address: