memcached原理

个人总结:

memcached的应用....
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using memcached;
using Memcached.ClientLibrary;
namespace memcached
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        //点击...
        private void button1_Click(object sender, EventArgs e)
        {
            MemcachedClient mc = new MemcachedClient();
            guo g = new guo();
            g.Name = "郭泽峰";
            g.Age = 24;
            mc.Set("123", g);
            mc.Set("12", "fffff");
        }
        private void button3_Click(object sender, EventArgs e)
        {
            char[] separator = { ',' };
            string[] serverlist = new string[] { "127.0.0.1:11211" };
            SockIOPool pool = SockIOPool.GetInstance();

            pool.SetServers(serverlist);
            pool.InitConnections = 3;
            pool.MinConnections = 3;
            pool.MaxConnections = 50;

            pool.SocketConnectTimeout = 1000;
            pool.SocketTimeout = 3000;

            pool.MaintenanceSleep = 30;
            pool.Failover = true;
            pool.Nagle = false;
            pool.Initialize();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            MemcachedClient mc = new MemcachedClient();
            textBox1.Text = ((guo)mc.Get("123")).Name.ToString() +"
"+ mc.Get("12").ToString();
        }
    }
    [Serializable]
    public class guo {
        public string Name { get;set;}
        public int Age { get; set; }
    }
}
====================================================
安装memached的命令:
在cmd命令行执行以下命令:
安装:   
    memcached.exe -d install

  启动:memcached.exe -d start

  卸载:memcached.exe -d uninstall

memcache:默认1024个链接:
命令链接:telnet ip memcache端口即可;
--add 参数:
add (key)(标志,为一个正整数,可以自己定义,比如1,是数组,2是json,淘出来可以反序列化)(缓存有效期0:不失效)(长度,单位字节)
--
缓存有效期:
1.单位是秒:
2.时间戳,到达那个时间就失效;
3.0:默认是30天,当然也可能等不到30天就会被拥挤出去。

----hash:通过计算从key计算存储地址,计算地址是有相同的概率,但是碰撞率比较低;
get
delete 后面可以加秒,几秒内不能再用。
replace 替换;
add 如果已经有键了再add,会不成功,只能replace

set: 如果没有键就add,有了就replace;

----秒杀:秒杀活动可以用这个来实现;
Incr 增长
decr 递减s
Incr count 1, 让count键值加1;

====统计:
命令:stats
启动时长,存过个多少个值,当前存了多少,历史链接数,当前链接数,要数据多少次(cmd_get),没找到(cmd_miss),命中几次(cmd_hits)
通过这些计算命中率:
====
flush all 清空所有。

======

内存碎片:空闲,但是无法使用,申请释放,形成的。
s
====memcached是如何克服内存碎片化的:
他先将内存划分成不同大小的内存块,比如88k的块和100的块,120的块
然后,根据存储内容大小,选择不同的内存块,如果是90kb,会选100的块
,其余的10kb指定浪费,但是没有办法。所以它不能完全克服内存浪费:
一句话,memcached是用slab allocator机制来管理内存的。
--当然可以根据自己网站的内存使用情况,可以设置chunk的大小。
---

也可以自定义内存的增长因子。默认是1.25.


-----------------------------------------

基本原理:预告把内存划分成数个slab仓库,在把仓库分割成不同尺寸,的trunk。根据大小选择
不同trunk。当比如80的trunk以使用完,后再来80的值,这个时候,不会选择100的trunk,而是
将老数据(过期)踢掉。
----
过期数据处理机制:

1.lazy expiration:它不会监视记录是否已经过期,之后get的时候,再清空
2.lru,最近最少使用。当内存不足的时候,会检索,最少使用的,然后踢掉。
---
值过期后,并不自动删除,只有get,或是内存不足,重新被占用。
这个过期,只是让用户看不到,并不是自动删除
惰性失效,减少cpu时间。

----被t原理:

当一个单元被请求时,会有计数器来判断,谁被使用最少,然后被踢掉。
---
就算是设置永久存储,也会被踢,老数据就会被踢。

------------
key的长度为250个字节:
value为1M
32最大内存为2G
64位不限
============================

memcached,需要自己建立负载均衡。
1.根据key,按照md5或其他,转为数字取膜,对应服务器编号即可。
(取膜算法不适合做集群,一旦一台挂后,重新n-1取膜,命中率只有n分之1)
除了n*(n-1)不受影响,其余的都发生了错位。导致命中率只有n分之1

2.我们采用一致性哈希:
1.假如我们有三台服务器a,b,c
2.引入虚拟节点,a变成了a1到a100 100台
b变成了b1到b100 100台
c变成了c1到c100 100台
3.然后我们将300个点均匀的打乱到一个圆环上,360度的圆环上均匀分布着abc各100个点,
按照顺时针方向,转移命中。当将key通过一定算法得到一个度数后,获取圆上的点上的机器
宕机后,转移到顺时针下一个方向上的机器,这样我们就实现了,如果一台机器当掉,我们
在不影响其他机器上的数据的同时,又将命中坏掉的机器上的数据均匀转移到了其他服务器上。
很有意思。(比如c坏掉之后,100个点,会均匀按照顺时针转移,所以a和b各承担本应该命中c的一半)

====实现一致性哈希:
1.我们需要将字符串转成一个整数的过程,crc32()函数可以实现,转化为(0-2)的32次方 数字;
2.我们将服务器地址ip+端口也用crc32()得到整数;放到list中,并从小到大排序
(增加虚拟节点,for循环64个,重起64个虚拟名字,添加到lists)必须拿到虚节点,得出实际服务器节点。
3.通过key,计算crc32,判断落到哪个点上。遍历list,知道小于一个节点,则,就选择对应的机器。
4.如果宕机一台机器,算出64个虚拟节点的crc32值,从list中删除即可。

=====memcached:雪崩现象:
一版由某个节点失效,导致其他节点的缓存命中率下降。缓存中的数据
需要去数据库查询,短时间内造成数据库服务器崩溃。(数据库需要来回重启好几次才可以)

或者由于缓存周期6个小时同时失效,造成数据库压力大。
所以让失效时间交错就可以了。

==========memcached:无底洞现象,
facebook爆出一个问题,链接效率低下,于是加了memcached服务器,但是不见好转,
--
原因是,虽然数据被更加分散,但是链接数平均还是没变,链接的节点也会增多。一次取一个和一次去两个
都是链接一次。
----解决方案,我们把瞬间查询的多个信息尽量放在一个memcached节点上。
比如查看个人主页的时候会显示用户姓名,年龄,身高
那我们的key不应该是user-133-age,user-133-name,user-133-height算出来的hash值,
而是user-133算出hash命中的节点,这样就会在同一机器上了。
所以取三者信息,只需要链接一次就可以。

======================老数据被踢:

内存满时,再塞可能会被踢。
1.因为被t的是不活跃的,不get的话,mem也不会知道哪些会失效。
惰性删除。

----解决办法,官方的做法是,将永久和非永久数据分开来存储。

memcache只能存储纯字符串。

原文地址:https://www.cnblogs.com/guozefeng/p/6907438.html