Memcache is a project of danga.com. It was first used to serve LiveJournal. Currently, many people around the world use this caching project to build their own large-load websites to share the pressure on the database. It can handle any number of connections and uses non-blocking network IO. Since its working mechanism is to open up a space in the memory and then create a HashTable, Memcached manages these HashTables by itself. Memcache official website: http://www.danga.com/memcached, more detailed information can be found here.
Why are there two names: Memcache and memcached? In fact, Memcache is the name of this project, and memcached is the name of its main program file on the server side. You know what I mean~~~~. One is the project name, and the other is the main program file name. I saw many people on the Internet who didn’t understand, so they used them interchangeably.
It is divided into two processes: memcache server installation and memcached client installation.
The so-called server-side installation is to install Memcache on the server (usually a Linux system) to store data.
The so-called client installation refers to PHP (or other programs, Memcache also has other good api interfaces) to use the functions provided by Memcache on the server side. PHP needs to be added with extensions.
<?php //连接 $mem = new Memcache; $mem->connect("db.bkjia.com", 12000); //保存数据 $mem->set('key1', 'This is first value', 0, 60); $val = $mem->get('key1'); echo "Get key1 value: " . $val ."<br />"; //替换数据 $mem->replace('key1', 'This is replace value', 0, 60); $val = $mem->get('key1'); echo "Get key1 value: " . $val . "<br />"; //保存数组 $arr = array('aaa', 'bbb', 'ccc', 'ddd'); $mem->set('key2', $arr, 0, 60); $val2 = $mem->get('key2'); echo "Get key2 value: "; print_r($val2); echo "<br />"; //删除数据 $mem->delete('key1'); $val = $mem->get('key1'); echo "Get key1 value: " . $val . "<br />"; //清除所有数据 $mem->flush(); $val2 = $mem->get('key2'); echo "Get key2 value: "; print_r($val2); echo "<br />"; //关闭连接 $mem->close(); ?>
If normal, the browser will output:
Get key1 value: This is first value Get key1 value: This is replace value Get key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd ) Get key1 value: Get key2 value:
Initialize a Memcache object: $mem = new Memcache;
Connect to our Memcache server. The first parameter is the IP address of the server, which can also be the host name. The second parameter is the open port of Memcache: $mem->connect("192.168.0.200", 12000);
Save a data to the Memcache server. The first parameter is the key of the data, used to locate a data. The second parameter is the content of the data that needs to be saved. Here is a string. The third parameter is a mark. , generally set to 0 or MEMCACHE_COMPRESSED. The fourth parameter is the validity period of the data, which means that the data is valid within this time. If this time passes, the data will be cleared by the Memcache server. The unit is seconds. If set to 0, it will be valid forever. We set 60 here, which is valid for one minute: $mem->set('key1', 'This is first value', 0, 60);
Get a piece of data from the Memcache server. It has only one parameter, which is the key to get the data. Here is the key1 set in the previous step. Now after getting this data, output the output:
$val = $mem->get(’key1′); echo "Get key1 value: " . $val;
Now use the replace method to replace the value of key1 above. The parameters of the replace method are the same as set, but the first parameter key1 must be the key to replace the data content. The final output is:
$mem->replace('key1', 'This is replace value', 0, 60); $val = $mem->get('key1'); echo "Get key1 value: " . $val;
Similarly, Memcache can also save arrays. The following is an array saved in Memcache, then retrieved and output:
$arr = array('aaa', 'bbb', 'ccc', 'ddd'); $mem->set('key2', $arr, 0, 60); $val2 = $mem->get('key2'); print_r($val2);
Now delete a piece of data, use the delte interface, the parameter is a key, and then you can delete the data of the key in the Memcache server. There is no result in the final output:
$mem->delete('key1'); $val = $mem->get('key1'); echo "Get key1 value: " . $val . "<br />";
Finally, we clear all the data saved on the Memcache server, and we will find that the data is gone. The final output key2 data is empty, and finally the connection is closed:
$mem->flush(); $val2 = $mem->get('key2'); echo "Get key2 value: "; print_r($val2); echo "<br />";
Websites that use Memcache generally have relatively large traffic. In order to relieve the pressure on the database, Memcache is used as a cache area to save part of the information in the memory, so that it can be accessed quickly on the front end. Then the general focus is on how to share database pressure and distribute it. After all, the memory capacity of a single Memcache is limited. I simply put forward my personal opinions here. I have not practiced them and should only be used as a reference.
Distributed Application
Memcache originally supports distributed distribution, but our client has been slightly modified to provide better support. Our keys can be encapsulated appropriately and regularly. For example, for a user-based website, each user has a User ID, so it can be extracted and accessed according to a fixed ID. For example, users starting with 1 are stored in the first On one Memcache server, the data of users starting with 2 is stored on the second Memcache server. The access data is first converted and accessed according to the User ID.
However, this has the disadvantage that it requires judgment on the User ID. If the business is inconsistent, or other types of applications may not be so suitable, then you can consider it based on your actual business, or think of a more suitable method.
Reduce database pressure
This is quite important. All data is basically stored in the database. Frequent access to the database each time leads to a severe decline in database performance and the inability to serve more users at the same time. For example, MySQL is particularly frequent. lock table, then let Memcache share the pressure on the database. We need a way to change the current architecture in a way that makes the changes relatively small and does not require large-scale changes to the front end.
A simple method I considered:
后端的数据库操作模块,把所有的Select操作提取出来(update/delete/insert不管),然后把对应的SQL进行相应的hash算法计算得出一个hash数据key(比如MD5或者SHA),然后把这个key去Memcache中查找数据,如果这个数据不存在,说明还没写入到缓存中,那么从数据库把数据提取出来,一个是数组类格式,然后把数据在set到Memcache中,key就是这个SQL的hash值,然后相应的设置一个失效时间,比如一个小时,那么一个小时中的数据都是从缓存中提取的,有效减少数据库的压力。缺点是数据不实时,当数据做了修改以后,无法实时到前端显示,并且还有可能对内存占用比较大,毕竟每次select出来的数据数量可能比较巨大,这个是需要考虑的因素。
我们上面的Memcache服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器被入侵,因为Mecache是以root权限运行的,况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。为了安全起见,我做两点建议,能够稍微的防止黑客的入侵或者数据的泄露。
内网访问
最好把两台服务器之间的访问是内网形态的,一般是Web服务器跟Memcache服务器之间。普遍的服务器都是有两块网卡,一块指向互联网,一块指向内网,那么就让Web服务器通过内网的网卡来访问Memcache服务器,我们Memcache的服务器上启动的时候就监听内网的IP地址和端口,内网间的访问能够有效阻止其他非法的访问。
# memcached -d -m 1024 -u root -l 192.168.0.200 -p 11211 -c 1024 -P /tmp/memcached.pid
Memcache服务器端设置监听通过内网的192.168.0.200的ip的11211端口,占用1024MB内存,并且允许最大1024个并发连接。
设置防火墙
防火墙是简单有效的方式,如果却是两台服务器都是挂在网的,并且需要通过外网IP来访问Memcache的话,那么可以考虑使用防火墙或者代理程序来过滤非法访问。一般我们在Linux下可以使用iptables或者FreeBSD下的ipfw来指定一些规则防止一些非法的访问,比如我们可以设置只允许我们的Web服务器来访问我们Memcache服务器,同时阻止其他的访问。
# iptables -F # iptables -P INPUT DROP # iptables -A INPUT -p tcp -s 192.168.0.2 –dport 11211 -j ACCEPT # iptables -A INPUT -p udp -s 192.168.0.2 –dport 11211 -j ACCEPT
上面的iptables规则就是只允许192.168.0.2这台Web服务器对Memcache服务器的访问,能够有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需要来做。