1. SockIOPool – SockIO池化管理,为上层提供的接口是实例化函数[主要是指定memcached服务器地址,各个
机器的权重];根据key&hashCode获取SockIO-网络连接句柄;根据服务器地址获取SockIO;关闭池。上层在获取
到SockIO后可以进行读写操作,在正常使用完SockIO后将其归还给池,如果在使用过程中出现问题则将这个网络
连接关闭,同时还暴露了SocketChannel提供了进行NIO编程的接口。
SockIOPool有在static可见范围维护一个String池名到SockIOPool的映射。
SockIO进入availPool或者busyPool都会把进入的时间写入,作为空闲时间或者使用时间的参考
------------------
2. SockIOPool属性
    boolean initialized = false – 初始化是否完成的标志,只有初始化完成后上层才能正常使用池
    int initConn = 10 – 初始化时对每个服务器建立的连接数目
    int minConn = 5 – 每个服务器建立最小的连接数,当自查线程发现与某个服务器建立连接数目小于这个数目时
    会弥补剩下的连接
    int maxConn = 100 -每个服务器建立最大的连接数,当自查线程发现与某个服务器建立连接数目大于这个数目
    时就会逐个检查这些连接的空闲时间是否大于maxConn,如果大于会关闭这些连接,直到连接数等于maxConn
    long maxIdle = 1000 * 60 * 5 – 最大空闲时间
    long maxBusyTime = 1000 * 30 – 最长租用时间,其使用主要有两点,一是自查线程会检查正在被租用的连接,
    如果发现已经被租用的时间超过这个值得,会将其从被租用的记录里剔除,并关闭这个连接;另一个应用是
    上层进行MUTIL操作时,读取所有的数据的时间不能超过这个时间。
    long maintSleep = 1000 * 30 – 自查线程周期进行工作,其每次休眠时间
    int socketTO = 1000 * 3 – Socket阻塞读取数据的超时时间
    int socketConnectTO = 1000 * 3 - Socket阻塞建立连接的等待时间
    boolean aliveCheck = false -根据key&hashCode获取SockIO时,通过hash bucket得到SockIO后,如果这个值
    是true会检查Socket是否已经连接,如果连接建立正常还会想服务器发送“version\r\n”的指令,并读取数据,这
    个过程没有出错才会返回SockIO给上层用,否则返回NULL。所以一般设置为false。
    boolean nagle = false – Socket的参数,如果是true在写数据时不缓冲,立即发送出去
    int hashingAlg = NATIVE_HASH – 池的hash bucket方式,主要是分为简单的hashCode取hash bucket数目的模
    和一致性哈希,前者在扩容时会造成命中率很大程度的下降,后者的好处是扩容时很大程度减少了缓存的重新
    分布
    String[] servers – memcached服务器地址配置
    Integer[] weights – memcached服务器权重配置
    List<String> buckets - hash bucket,一个服务器地址,其权重是N,则往这个bucket中添加N个服务器地址
    TreeMap<Long, String> consistentBuckets – 一致性哈希表:一个服务器地址,其权重是N,则迭代0 - N-1,取
    字符串服务器地址+i的MD5值,将这个MD5值分成4段,每段转换成Long值,将这个Long值到服务器地址放入
    到一致性哈希表中
    Map<String, Date> hostDead – 用来记录本地和哪个服务器地址建立连接失败的最近时间的MAP
    Map<String, Long> hostDeadDur – 如果hostDead包含服务器地址,说明上次建立连接失败了,那么会到
    hostDeadDur里取这个服务器没必要尝试连接时间间隔的值,如果上次失败时间+没必要尝试连接时间间隔则
    不会发起连接。在每次连接服务器失败后,会替换hostDead里最近时间,同时替换hostDeadDur的时间间隔
   值,这个值初始是1000ms,每失败一次翻倍一次。
    Map<String, Map<SockIO, Long>> availPool – 当前可用的连接记录
    Map<String, Map<SockIO, Long>> busyPool – 当前工作的连接记录
    Map<SockIO, Integer> deadPool – 用来保持应该关闭连接的SockIO,自查线程会将里面的所有的SockIO的连接
   关闭
    boolean failover/failback
------------------
3. 池初始化
在初始化阶段主要是完成一些值的初始化,再就是根据hashingAlg来设置hash bucket,如果是
CONSISTENT_HASH则使用上面提到的一致性HASH算法建立一致性哈希表,如果不是则使用上面提到的建立
hash bucket,接下来根据initConn和所有服务器地址创建数目为initConn的连接数目。如果maintSleep大于0则
启动整个连接池的自查线程。其中创建连接的逻辑如下:如果hostDead和hostDeadDur都持有一个服务器地址
的时候,会看最近失败时间+没必要连接时间间隔是否大于当前时间,大于的话直接放弃创建连接过程退出,
小于则发起连接,发起连接创建有三种情况,一种是在时间期限内创建成功,则清空其可能在hostDead和
hostDeadDur的记录,再将这个连接放入到availPool记录里面;一种是连接没有创建成功则将SockIO放入到
deadPool里给自查线程关闭连接和释放资源;最后一种是由于网络异常或者超时异常,第二种和第三种情况
发生则需要往hostDead和hostDeadDur里添加这个服务器地址的相关记录,同时将availPool里的这个服务器
地址的记录清除。
------------------
4. 租还SockIOPool
a. key & hashCode - 租
1. 先根据key & hashCode到hash bucket里找到其应该连接的服务器地址:如果有hashCode则直接使用
hashCode,没有则根据hashingAlg取hash值。如果是一致性哈希算法则到consistentBuckets里找计算出的大hash
值的点,没找到则取第一个;如果是其他的则hash bucket取模。
2. 到availPool里根据服务器地址找到可用的连接列表,迭代这个列表,如果有可用的则从availPool取出,
并加入到busyPool,如果不可用则加入到deadPool给自查线程关闭连接。经过上面的过程还没有得到连接则调用
上面提到的创建连接的逻辑,如果创建成功加入到busyPool。
3. 在得到一个连接SockIO后,再进行一些检查,如果连接不可用则加入到deadPool,可用如果aliveCheck
为true则会进行上面提到的自检操作,如果自检发生错误则从busyPool中移除并关闭连接。如果在2没有得到连
接,并且failover为false则直接返回不再尝试连接到其他机器了;否则会组装一些新的key到hash bucket里去找剩
下的服务器地址按2建立连接。
b. host - 租
到availPool里根据服务器地址找到可用的连接列表,迭代这个列表,如果有可用的则从availPool取出,
并加入到busyPool,如果不可用则加入到deadPool给自查线程关闭连接。经过上面的过程还没有得到连接则调用
上面提到的创建连接的逻辑,如果创建成功加入到busyPool。
c. 还
将此连接SockIO从busyPool的记录中移除,如果连接可用则将连接加入到availPool的记录里面。
------------------
5. 自查线程
自查线程主要提供两个逻辑,启动和关闭,启动时周期性调用池的自查逻辑,关闭则通过一个是否停止标志来的
设置来标记停止,在中断可能正在休眠的自查线程。
池的自查逻辑主要是:
a. 到availPool检查各个服务器目前可用连接数目的个数,如果小于minConn则创建连接来弥补差额,创建的新
的连接加入到availPool中。
b. 再到availPool检查各个服务器目前可用连接数目的个数,如果大于maxConn会逐个检查这些连接的空闲时间
是否大于maxConn,如果大于会关闭这些连接,直到连接数等于maxConn。空闲时间的计算就是当前时间和这个
连接进入availPool时间的差值。
c. 到busyPool检查,发现某个连接已经被租用的时间超过这个值得,会将其从被租用的记录里剔除,并将其加入
到deadPool中。
d. 迭代deadPool中所有的连接,关闭这些连接。
------------------
6. 关闭过程主要是先停止自查线程,直到自查线程结束运行,再迭代availPool和busyPool将里面的网络连接
SockIO,关闭SockIO主要是关闭输入输出流,关闭Socket。

SockIOPool的更多相关文章

  1. memcached 的 SockIOPool 概念

    池的概念 SockIOPool 首先来看下属性 SockIOPool属性 boolean initialized = false – 初始化是否完成的标志,只有初始化完成后上层才能正常使用池 int ...

  2. Memcached Memcached.ClientLibrary.SockIOPool”的类型初始值设定项引发异常

    又一次遭遇"xxx类型初始值设定项引发异常" 下了个c#实现的轻量级IoC开源项目,可是在本地使用时发现一运行就捕捉到"类型初始值设定项引发异常"的异常信息,调 ...

  3. Key/Value之王Memcached初探:二、Memcached在.Net中的基本操作

    一.Memcached ClientLib For .Net 首先,不得不说,许多语言都实现了连接Memcached的客户端,其中以Perl.PHP为主. 仅仅memcached网站上列出的语言就有: ...

  4. ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存

    ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完 ...

  5. memcached安装及.NET中的Memcached.ClientLibrary使用详解

    序言 吹吹牛逼先,借我你的20分钟,保证你在.net中使用memcached缓存数据,畅通无阻,提升数据读取效率,分担数据库压力,便不在话下. 本篇主要说下:memcached分布式缓存的负载均衡配置 ...

  6. Memcache缓存系统构建一

    在如今这个高效率的社会中,怎样将这个高效率应用到自己的程序中,是一个值得追寻和值得探讨的问题.因为这个memcache能够很好的提高检索速度,提升用户体验,而且重要的是减少数据库的访问.这就大大的提高 ...

  7. 【实践】Memcached实例解析

    一.关于Memcached Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是一种基于内存的Key-Value存储,用来存储小块的任意数据(字符串.对象).这些 ...

  8. Key/Value之王Memcached初探:三、Memcached解决Session的分布式存储场景的应用

    一.高可用的Session服务器场景简介 1.1 应用服务器的无状态特性 应用层服务器(这里一般指Web服务器)处理网站应用的业务逻辑,应用的一个最显著的特点是:应用的无状态性. PS:提到无状态特性 ...

  9. Memcache学习整理

    一.Memcache 是什么? 组成:程序进程管理.Socket 程序进程:Memcache把内存先分成几个大份,每一份分成多个小份.例如:小份中有5M...0.9M.0.8M.....0.1M,一份 ...

随机推荐

  1. 关于Java的File类、字节流和字符流

    一.File类: 在Windows下的路径分隔符(\)和在Linux下的路径分隔符(/)是不一样的,当直接使用绝对路径时,跨平台会报No Such file or diretory异常. File中还 ...

  2. 如何在 Ubuntu 上搭建网桥

    导读作为一个 Ubuntu 16.04 LTS 的初学者.如何在 Ubuntu 14.04 和 16.04 的主机上搭建网桥呢?顾名思义,网桥的作用是通过物理接口连接内部和外部网络.对于虚拟端口或者 ...

  3. 【DataStrcutre】Introduction and description of Binary Trees

    [Definitions] Here is the recursive definition of a binary tree: A binary tree is either the empty s ...

  4. java将SSL证书导入系统密钥库

    之前安装JIRA和Confluence,配置了SSL证书之后遇到应用程序链接的问题: SSL证书不被信任,导致JIRA和Confluence无法关联. 尝试过很多办法无果之后打算放弃. 最终还是放弃了 ...

  5. 算法笔记_124:密码脱落(Java)

    一 问题描述 X星球的考古学家发现了一批古代留下来的密码.这些密码是由A.B.C.D 四种植物的种子串成的序列.仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串).由于年代久远,其中 ...

  6. 算法笔记_071:SPFA算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...

  7. LR学习笔记之—参数和变量

    一.LR中参数的使用 LR中参数默认使用“{}”来表示,如果想要修改,可以再General Options/Parameterization设置参数的边界字符 经常用到的函数: lr_save_str ...

  8. push和unshift方法

    push和unushift都是向数组插入元素. push是向数组尾部插入元素. unshift是向数组头部插入元素. 共同点:都可以一次插入多个元素. arrayObject.push(newelem ...

  9. 【leetcode】Reorder List (python)

    问题的思路是这样: 循环取头部合并,事实上也能够换个角度来看,就是将后面的链表结点,一次隔空插入到第一部分的链表中. class Solution: # @param head, a ListNode ...

  10. 【PPT】PPT倒计时动画的制作方法 5.4.3.2.1...

    制作步骤: 1.输入数字 在PPT空白页面中插入横排文本框,输入数字54321,并修改数字字体和大小. 2.修改数字的间距,让数字重叠在一起 字体间距 - 其他间距 - 紧缩 - 输入 150 3.选 ...