• memcached四大注意事项(key长度,空格限制,最大item)


    1.   key值最大长度?

    memcached的key的最大长度是250个字符

    注意250是memcached服务器端内部的限制(可以修改)

    如果您使用的客户端支持"key的前缀"或类似特性,那么key(前缀+原始key)的最大长度是可以超过250个字符的。

    我们推荐使用使用较短的key,因为可以节省内存和带宽。

    key只要不重复就行,如果太大浪费内存。

    2.key 不能有空格和控制字符

    the key must not include control characters or whitespace.

    1. item的过期时间限制?

    过期时间最大30

    如果不注意这个细节,过期时间设置大于了30天,值会设置不进缓存

    1. 最大能存储多大的单个item?

    1MB

    如果你的数据大于1MB,可以考虑在客户端压缩或拆分到多个key中。

    memcached参数中文解释

    memcached 1.4.2
    -p <num>      监听的TCP端口(默认: 11211)
    -U <num>      监听的UDP端口(默认: 11211, 0表示不监听)
    -s <file>     用于监听的UNIX套接字路径(禁用网络支持)
    -a <mask>     UNIX套接字访问掩码,八进制数字(默认:0700)
    -l <ip_addr>  监听的IP地址。(默认:INADDR_ANY,所有地址)
    -d            作为守护进程来运行。
    -r            最大核心文件限制。
    -u <username> 设定进程所属用户。(只有root用户可以使用这个参数)
    -m <num>      所有slab class可用内存的上限,以MB为单位。(默认:64MB
                  (译者注:也就是分配给该memcached实例的内存大小。)
    -M            内存用光时报错。(不会删除数据)
    -c <num>      最大并发连接数。(默认:1024)
    -k            锁定所有内存页。注意你可以锁定的内存上限。
                  试图分配更多内存会失败的,所以留意启动守护进程时所用的用户可分配的内存上限。
                  (不是前面的 -u <username> 参数;在sh下,使用命令"ulimit -S -l NUM_KB"来设置。)
    -v            提示信息(在事件循环中打印错误/警告信息。)
    -vv           详细信息(还打印客户端命令/响应)
    -vvv          超详细信息(还打印内部状态的变化)
    -h            打印这个帮助信息并退出。
    -i            打印memcached和libevent的许可。
    -P <file>     保存进程ID到指定文件,只有在使用 -d 选项的时候才有意义。
    -f <factor>   不同slab class里面的chunk大小的增长倍率。(默认:1.25)
                  (译者注:每个slab class里面有相同数量个slab page,每个slab page里面有chunk,且在当前slab class内的chunk大小固定。
                  而不同slab class里的chunk大小不一致,具体差异就是根据这个参数的倍率在增长,直到分配的内存用尽。)
    -n <bytes>    chunk的最小空间(默认:48)
                  (译者注:chunk数据结构本身需要消耗48个字节,所以一个chunk实际消耗的内存是n+48。)
    -L            尝试使用大内存页(如果可用的话)。提高内存页尺寸可以减少"页表缓冲(TLB)"丢失次数,提高运行效率。
                  为了从操作系统获得大内存页,memcached会把全部数据项分配到一个大区块。
    -D <char>     使用 <char> 作为前缀和ID的分隔符。
                  这个用于按前缀获得状态报告。默认是":"(冒号)。
                  如果指定了这个参数,则状态收集会自动开启;如果没指定,则需要用命令"stats detail on"来开启。
    -t <num>      使用的线程数(默认:4)
    -R            每个连接可处理的最大请求数。
    -C            禁用CAS。
    -b            设置后台日志队列的长度(默认:1024)
    -B            绑定协议 - 可能值:ascii,binary,auto(默认)
    -I            重写每个数据页尺寸。调整数据项最大尺寸。

    Memcached.ClientLibrary的key-server映射比较简单,基本原理就是对key求hash值,用hash值对服务器数量进行模运算,该key值被分配到模运算结果为索引的那台server上

    Load Balance配置

    通过SocketIOPool的Weights属性设置。假如有server A、B、C,根据其机器配置决定负载分别为40%、30%、30%,则如下配置即可:
    pool.SetServers(new string[] { "A", "B", "C" });
    pool.SetWeights(new int[] { 4, 3, 3 });

    SocketIOPool的私有属性_buckets用于存放key-server映射的索引,内容为server的地址。为实现负载均衡的设置,key-server映射时不是直接对服务器数量进行模运算,而是对_buckets的count取模。如果某个服务器的Weights被设置为2,则该服务器在_buckets中会放2条记录,以这样的方式实现各服务器之间的负载分配
    需要注意,如果设置了Weights,会给socket pool的设置带来影响。比如socket pool设置初始化连接数为5,按照上面Weights的设置,初始化时服务器A会创建4*5=20个连接,而B和C会分别创建15个连接。但是有的情况下又是以server为单位进行控制的,例如维护线程在检查最小连接数、最大连接数时,不管Weights如何设置,均以server为单位做检查。这是代码处理上不一致的问题

    压缩

    启用数据压缩,需要设置MemcachedClient对象的EnableCompression属性,并设置CompressionThreshold值
    CompressionThreshold是启用压缩的阀值,默认为15k,即数据超过15k大小时将使用ICSharpCode.SharpZipLib对数据进行压缩
    memcached 的通讯协议中,存数据时可以为每个数据项提供一个16位的flag,用以对数据进行特殊标记,取数据时memcached将该标记原样返回。 Memcached.ClientLibrary使用flag记录数据是否有压缩、是否使用了序列化等,读取服务器返回的数据时,如果flag表明该数据有压缩,则使用ICSharpCode.SharpZipLib对其解压

    key的hash算法支持

    因为Memcached.ClientLibrary直接使用hash值进行key-server映射,因此hash算法起的作用比较大。内部支持3种hash算法
    HashingAlgorithm.Native: 即使用.NET本身的hash算法,速度快,但与其他client可能不兼容,例如需要和java、ruby的client共享缓存的情况
    HashingAlgorithm.OldCompatibleHash: 可以与其他客户端兼容,但速度慢
    HashingAlgorithm.NewCompatibleHash: 可以与其他客户端兼容,据称速度快
    他允许使用其他hash算法,使用方式是MemcachedClient对象的Get、Set等方法,都有提供hash值的重载版本,client自己使用其他hash算法对key求hash值,然后传给MemcachedClient

    同时使用多个SocketIOPool

    比如已有系统A、B,分别使用自己的memcached server,之间不共享,现在开发系统C需要同时使用A、B的memcached server,则系统C中可以创建2个SocketIOPool;又比如,在系统中希望使用2个独立的memcached server,1个用于存放一些readonly、特殊的缓存数据,另一部分存放其他正常缓存数据等;比如web server上专门用一组memcached server存放用户session状态数据,用另一组存放应用层缓存数据等等
    使用方法:可以对SocketIOPool设置名称,创建MemcachedClient对象时指定SocketIOPool的名称

    代码结构、处理方式


    只有3个类完成主要功能

    SockIO: 负责socket通讯,例如创建socket对象、建立连接、读、写等。socket对象也是一直保持连接状态的
    连接超时的管理:
    他提供了连接超时的配置选项,这在高并发的情况下遇到server不可用时,可以用来防止大量socket连接阻塞执行线程(windows自身的连接超时时间以秒为单位)
    windows的socket连接超时通过注册表配置,运用于整个windows,而API在建立socket连接时并没有连接超时时间设置
    Memcached.ClientLibrary 的实现方式为,如果配置了连接超时时间,每次创建socket连接时新开一个线程,用他创建sokcet对象并进行连接,执行线程则不停的sleep并检查新线程是否连接成功,如果连接成功则返回socket连接,否则达到超时时间时,主线程直接返回,新线程则交由.NET和windows进行释放
    其实现上仍存在一个待处理问题,即需要对新开线程的数量进行管理,否则虽然执行线程没有被阻塞,还是会浪费大量线程资源尝试socket连接

    SockIOPool:
    1. socket pool的管理
    2. 服务器节点状态管理
    3. key-server映射管理
    4. failover处理
    5. 负载均衡的实现

    socket pool管理

    1. SocketPool的私有属性_availPool存放空闲的socket列表,_busyPool存放正在作业的socket列表
      _availPool和_busyPool都是HashTable,key为server的string,值为一个HashTable,存放 SocketIO实例(这个HashTable的key为SocketIO实例对象,值为加入pool的时间,这个加入时间将用于最大空闲时间、最大工作时间的控制)
    2. SocketPool.Initialize时,为每个server创建InitConnections数量的socket连接,放入空闲列表中
      如前面所说,实际是针对每个Weights单位创建初始化连接数量的
    3. 处理请求时,如果空闲列表中存在,则从空闲列表取出socket,放入工作列表,并返回给请求者;作业结束后如果socket仍然是连接状态,则从工作列表中删除,放回空闲列表
      如果空闲列表中没有可用socket,则创建socket对象并返回给请求者
      创建过程的处理:并不是每次仅仅创建一个socket对象,第一次遇到socket不够用时将创建1个,第二次创建2个,第三次4个,每次创建数量将增倍,单次创建的最大数量为MinConnections/4(MinConnections小于4时取MinConnections)。多创建的 socket放入空闲列表,最后一个放入工作列表并返回给请求者。SocketIOPool的_createShift存放下次创建时的倍数,key为 server的string,值为倍数,维护线程在释放空闲列表中多余的socket之后会重置这个倍数
      这样的处理方式,有利于某时间段内请求快速上升时的处理性能
    4. 处理请求时如果发生socket通讯异常,socket对象被真正释放掉,并从工作列表中移除
      如果发生其他类型异常,则将socket从工作列表移除并放入空闲列表
    5. 如果有设置MaintenanceSleep,则每个socket pool会开一个维护线程,每间隔MaintenanceSleep时间执行一次维护工作
      维护内容包括:最小连接数、最大连接数、最长空闲时间、最长作业时间的检查控制。最小连接数和最大连接数是以空闲队列的数量做控制的,并不包含当前作业的 socket数量。最长空闲时间、最长作业时间以_availPool、_busyPool中记录的时间为基准,socket对象每次加入 _availPool和_busyPool时都记录了加入时间,socket作业时间如果超过最长作业时间设置,该socket会被强行中断掉。 socket超过最大连接数设置时,并不是一次全部把超过的数量全部释放掉,类似于创建连接时的处理方式,也是逐次递减的释放socket对象,直到等于最大连接数设置

    节点状态管理

    1. SocketIOPool的私有属性_hostDead存放死节点
      key为server的string,值为加入_hostDead的时间;_hostDeadDuration存放下次尝试连接死节点的时间间隔,key为server的string,值为间隔时间
    2. 如前面Load Balance配置中提到的,_buckets存放了当前所有节点,并且根据Weights的设置进行分配。节点变成dead server时也不会从_buckets中移除
    3. 某个时间点某个server变得不可用时:
      作业中的socket将发生异常,直接被释放掉
      空闲队列中的socket仍会被分配给后续的请求,但这些请求将发生异常,将socket释放,请求的处理失败
      最后该server相关的socket会全部被释放掉,新的请求将尝试创建新的socket连接
    4. 任何时候创建新的socket连接时:
      如果发生socket异常,则该节点被添加到_hostDead中,_hostDeadDuration的初始化值设置为100ms
      后续针对dead server的创建请求,依赖于failover的设置
      如果处理结果为节点可用了,则将该节点从_hostDead和_hostDeadDuration中移除,该节点恢复为正常工作节点

    failover处理

    用于在节点发生故障变成死节点时,提供后续的处理机制
    启用failover(设置为true)时:
    每隔一定时间间隔才尝试重新连接该节点,期间原来映射到该节点的key将被重新映射到其他可用节点上,该节点恢复之后,这些key会重新映射回该节点
    具体处理过程为:
      新的请求被映射到dead server时,检查_hostDeadDuration
      如果还没有达到设定的时间间隔,则重新将key映射到其他可用server进行处理
      如果时间间隔已经到达,则尝试重新连接,连接成功会将该节点从_hostDead中移除,连接失败则将_hostDeadDuration中对应的间隔时间翻倍,即下次将等待更长的时间再尝试连接
    禁用failover时:
    任何时候新的请求被映射到dead server上,都尝试重新建立socket连接,如果连接建立失败,给客户端返回null值(get、gets等命令)或者是操作失败(返回false值,对于set、add等命令)

    MemcachedClient: 为客户端提供各种操作,负责各种命令的实现。也包括压缩、解压的处理,序列化、反序列化等。

    基于.NET平台的客户端了:

    据我总结,大概常见的有三四种吧。必要的类库或者源码,我都将提供给大家下载。

    1).NET memcached client library

    Memcached .NET客户端的类库,目前大概只支持.NET1.0和.NET2.0,笔者没仔细研究这个,估计这个已经过时啦。   

    2)enyim.com Memcached Client

    源码地址:点击下载源码        (开源项目,可提供研究学习) 

    Enyim也是应用比较广泛的Memcached .net客户端,和之前的Memchachedonet 客户端相比,分布式算法应该做了相应优化

    3)Memcached Providers

    下载地址:点击下载      

    Memcached Providers的官网上有一份PDF的文档,是教你怎么配置的。

    4) BeIT Memcached

     

     
  • 相关阅读:
    文件数据分析制作过程【1】
    VBA学习(4)
    QTP9.2 .net与java插件破解
    GPRS开发系列文章之实战篇
    time_t到.NET的转换
    RAS函数
    GPRS开发系列文章之入门篇
    [转]惹恼程序员的十件事
    好玩和可爱的网站
    GPRS开发系列文章之进阶篇
  • 原文地址:https://www.cnblogs.com/westfruit/p/6992874.html
Copyright © 2020-2023  润新知