个人总结:
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() +"\r\n"+ 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只能存储纯字符串。