1. 配置Memcached
1.1. 命令行参数
Memcached带有基本文档关于其命令行参数。通过memcached -h或man memcached查看最新的文档。服务努力包含最合理的默认参数。当第一次建立memcached的时候,你将注意-m, -d和-v
-m 告诉memchaced用多少内存来存储数据项(单位:M)。注意,这不是全局的内存限制,因此memcached将使用多于设定的一定百分比的内存。设置这个为安全值,在1.4.x或更早版本上少于48M将不会很好的工作。
-d 告诉memchaced成为守护进程。如果你从一个初始脚本运行,你可能不会设置这个。如果你第一次使用memcached,不用-d启动能学习并观察它。
-v 控制输出到STDOUT/STDERR的详细信息。多个-v增加信息,单独一个输出附件的启动信息,多个将输出更多的关于请求命中memcached的信息。如果你好奇于看到一个测试脚本是否做着你期望的事情,在前端运行,并且输出少量verbose信息是一个好的注意
。
其他参数有合理的默认值,只在有必要的时候你才需要改变它们。
1.2. 初始脚本 (init script)
如果你已经从你的OS软件包管理系统安装了memcache,可能它已经有一个初始脚本。它们也有可选的方法来配置memcache启动的参数,如通过/etc/sysconfig/memcached文件。确保你在开始编辑初始脚本或你自己写之前检查了这些。如果你在自己构建memcached,代码包的'scripts/'目录中包含了几个初始脚本的例子。
1.3. 多个实例
运行多个本地memcached对象是没有必要的。如果你在维护一个开发者环境,或本机测试集群,只要改变监听端口,如:memcached -p 11212.有一个未合并的(在写这个时)初始脚本例子集合,用于管理多个实例,是关于bug 82. 这个将可能在1.4.6版本被合并(以某种方式)。
1.4. 网络
默认情况memcached监听TCP和UDP端口,都是11211. -l 允许你绑定指定的端口或IP地址。Memcached没有花费很多力气,来确保来自互联网随机链接的防卫性。所以你必须不要将memcached直接暴露给互联网,或其他任何不能信任的用户。使用SASL验证可能会有帮助,但不是完全可靠的。TCP
-p 修改它监听的TCP端口。当通过-p改变端口时,UDP端口也将随着改变。
UDP
-U 修改UDP端口,默认打开。UDP对于获取或设置小的数据项有用,但对操作大的数据项不是很有意义。设置为0将关闭它。
Unix Sockets
如果你想限制一个进程只能被一个本地用户访问,或只是不希望通过网络暴露,一个unix域socket可以被使用。-s <file> 是你想要的参数。如果使之生效,TCP/UDP将被关闭。
1.5. 连接限制
默认情况下最大的并发连接数设置为1024, 正确配置很重要。memcached超出的连接会被挂起等待slots空闲。你可以监测你的实例是否已经运行超出连接数,通过发送一个stats命令并观察"listen_disabled_num",这个值应该是0或接近0.Memcache可以非常简单地扩大连接数。每个连接的内存开销较低(连接闲置是更低),所有不要担心设置得过高。
假如说你有5台webservers, 都运行apache。每个apache进程的MaxClients设置为12. 这意味者你收到的最大并发连接数是5*12 (60). 如果可能总要留少量额外的连接开放,用于管理任务,添加更多的webservers,定时任务/脚本/等。
1.6. 线程
线程用于跨CPU扩张memcached, 它的模型是通过"工作者线程",即每个线程尽量让它自己对应进程可用。因为使用libevent允许并发连接下的良好扩展性,每个线程可以处理多个客户端。这于一些webservers不同,如果apache,对每个活动的client连接使用一个进程或一个线程。因为memcached是高效的,少量的线程数是可以的。在webserver领域,意味者比起apache它更像nginx。
默认情况下分配4个线程,除非memcached运行情况极端艰难,你不应该将这个数字设置得更大。设置为非常大的值(80+)并不会让他运行的更快。
1.7. 检查运行配置
$ echo "stats settings" | nc localhost 11211STAT maxbytes 67108864
STAT maxconns 1024
STAT tcpport 11211
STAT udpport 11211
STAT inter NULL
STAT verbosity 0
STAT oldest 0
STAT evictions on
STAT domain_socket NULL
STAT umask 700
STAT growth_factor 1.25
STAT chunk_size 48
STAT num_threads 4
STAT stat_key_prefix :
STAT detail_enabled no
STAT reqs_per_event 20
STAT cas_enabled yes
STAT tcp_backlog 1024
STAT binding_protocol auto-negotiate
STAT auth_enabled_sasl no
STAT item_size_max 1048576
END
酷吗?在'stats'和'stats settings'之间,你可以重复检查到,你让memcache做的正是它在尝试做的。
2. 客户端配置
2.1 共通的客户端配置
在某些重要的方面大多客户端是相似的。它们可能以不同方式实现相同的想法,但它们包含很多共通的概念。2.1.1 哈希 (Hashing)
所有客户端至少支持一种方法在服务器之间来"hashing"键。需要记住的是,默认情况下它们是互不通用的。如果你正在使用perl Cache::Memcached,并期望以某个PHP客户端相同的方式来解决键的问题,你将陷入麻烦。对此也有例外,基于libmemcached的客户端都是用同样的哈希算法。
2.1.2 一致性哈希
一致哈希(Consistent Hashing)是一种对于增加或移除服务器,能够更稳定的键(keys)分发的模型。在通常的hashing算法中,改变服务器数目会使得很多键(keys)被重新映射到不同的服务器,导致大量的缓存失效(cache missing)。一致哈希描述了映射键到一个服务器列表的方法,增加或移除服务器产生很小的键映射偏移。所以简单的说,用常见的哈希函数,增加第11个服务器会导致40%+的键突然指向不同的服务器。
然而,使用一致性哈希算法,增加第11个服务器只会导致少于10%的键被重新分配。实践上值会有不同,但这显然是有帮助的。
TODO:我知道关于这个有更好的讨论链接可用。能帮助找到它?我总是不能足够好的描述。
2.1.3 配置一致的服务器
当增加服务器到你的配置时,需要注意你支持客户端的服务器列表都保持准确的一致。如果你有3个web服务器,并且每个webserver都运行了一个memcached实例,你可能会想聪明的做法是将"local"实例的地址设置为"localhost"。这将不会按期望的工作,因为现在不同webserver间的服务器(memcached)是不同的。意味着,webserver 1与webserver 2的键映射将不同,这会导致你的用户和商业开发者发疯。
顺序也是重要的,有些客户端会排序你提供的服务器列表,但其他的不会。如果你有"A B C"服务器列表,在所有地方都按"A B C"列出。
使用Puppet/Chef/rsync/任何其他必要的(工具)来确保这些文件是同步的。
2.1.4 权重"Weighting"
给定一个不完美的世界,有时你可能有一个memcached实例有比其他有更多的RAM可用。有些客户端将允许你对大的server用更多的"权重"。其他的允许你多次指定一个服务器,使之被选择的机会更大。不管哪种方式,你最好很好的验证"weighting"是否正起到你期望的作用。
2.1.5 故障,或故障迁移
当一个server不可用或提供了一个无效的响应你的客户端会怎么做。在memcached之前的时间里,通过尝试列表中的下一个服务器,来进行默认的故障迁移。这种方式如果一个服务器宕机了,它的keys将被重新分配到其他memcached实例,并且都很好的迁移了。
然而,有很多方式来杀死一个服务。有时候它们甚至不像已经停止了。给定下面的场景:
。系统管理员Bob经过Server B并且将它的网线接口碰出来了
。Server B的keys的get被重新转发到其他实例
。系统管理员Bob是一个细心的同事,并负责的将网线重新装回去了
。Server B的keys的get有回到自身
现在所有事情变得可怕,在Bob将网线装回之前,你做的所有更新都丢失了,并且旧的数据被呈现给了用户。而且会变得更糟如果:
。如果Server B的网线接口被Bob弄坏了,并且之后从插口中落出来了
现在你的数据又回到另外一个集合。令人厌烦。
另外一个错误的客户端功能,会在一个服务器失去联系时修改服务器列表,停止重新映射很多本该映射的键(keys)。
如果可能,现代生活鼓励使用"Failure"。即是,如果你意图获取或存储cache数据的服务器不可用,简单的作为cache未命中(miss)来处理。如果有Server B类似问题,可能会仍在新旧数据间变更,但影响被降低了。
2.1.6 压缩
压缩大的值是一个很好的方法来获得更多内存空间。压缩可以为一些值节约大量内存,并且潜在的降低了延迟,因为小的数据值能更被在网络中获取。大多数客户端支持通过数据大小阀值来使压缩生效或失效,有些是基于每个数据项的。小的数据项并不能从继续减小数据获益,而不过是浪费CPU.
2.1.7 管理连接对象
一个常见的首次使用失败是,无论你做什么,你看起来都与memcached失去连接了。你的小服务器分配了50,000个连接到memcached,并且你不知道发生了什么。谨慎管理你的连接对象们!如果你每次想要连接memcached时都初始化一个连接对象,很可能你的连接泄露了。
有些客户端(像PHP的)有不那么明显的方式来管理打开了多少个连接。不断的调用'addServer()'可能只会造成连接泄露,即便是你已经增加了一个server. 阅读你的客户端文档以确认什么行为创建连接,而什么不会。