首页 » memcache » 正文

memcache 集群安装配置

 memcached存在的问题:

  1. 本身没有内置分布式功能,无法实现使用多台Memcache服务器来存储不同的数据,最大程度的使用相同的资源;无法同步数据,容易造成单点故障。(memagent代理实现集群)
  2. 在 Memcached中可以保存的item数据量是没有限制的,只要内存足够 。
  3. Memcached单进程最大使用内存为2G,要使用更多内存,可以分多个端口开启多个Memcached进程
  4. 最大30天的数据过期时间,设置为永久的也会在这个时间过期,常量REALTIME_MAXDELTA   60*60*24*30控制
  5. 最大键长为250字节,大于该长度无法存储,常量KEY_MAX_LENGTH 250控制
  6. 单个item最大数据是1MB,超过1MB数据不予存储,常量POWER_BLOCK 1048576进行控制, 它是默认的slab大小
  7. 最大同时连接数是200,通过 conn_init()中的freetotal进行控制,最大软连接数是1024,通过 settings.maxconns=1024 进行控制
  8. 跟空间占用相关的参数:settings.factor=1.25, settings.chunk_size=48, 影响slab的数据占用和步进方式
  9. memcached是一种无阻塞的socket通信方式服务,基于libevent库,由于无阻塞通信,对内存读写速度非常之快。
  10. memcached分服务器端和客户端,可以配置多个服务器端和客户端,应用于分布式的服务非常广泛。
  11. memcached作为小规模的数据分布式平台是十分有效果的。

memcached是键值一一对应,key默认最大不能超过128个字 节,value默认大小是1M,也就是一个slabs,如果要存2M的值(连续的),不能用两个slabs,因为两个slabs不是连续的,无法在内存中 存储,故需要修改slabs的大小,多个key和value进行存储时,即使这个slabs没有利用完,那么也不会存放别的数据。

集群配置:

由于Memcached服务器与服务器之间没有任何通讯,并且不进行任何数据复制备份,所以当任何服务器节点出现故障时,会出现单点故障,如果需要实现HA(高可用集群),则需要通过另外的方式来解决。

通过Magent缓存代理,防止单点现象,缓存代理也可以做备份,通过客户端连接到缓存代理服务器,缓存代理服务器连接缓存连接服务器,缓存代理服务器可以连接多台Memcached机器可以将每台Memcached机器进行数据同步。如果其中一台缓存服务器down机,系统依然可以继续工作,如果其中一台Memcached机器down掉,数据不会丢失并且可以保证数据的完整性。具体可以参考:http://code.google.com/p/memagent/

memcache集群的实现:

memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现

以下是集群的两种方式:

使用代理:

2

不使用代理:

1

memcached的分布式:

Memcached作为集中式Cache,就存在着集中式的致命问题:单点问题,Memcached支持多Instance(实例)分布在多台机器上,仅仅只是解决了数据全部丢失的问题,但是当其中一台机器出错以后,还是会导致部分数据的丢失,一个篮子掉在地上还是会把部分的鸡蛋打破。

因此就需要实现一个备份机制,能够保证Memcached在部分失效以后,数据还能够依然使用,当然大家很多时候都用Cache不命中就去数据源获取的策略,但是在SIP的场景中,如果部分信息找不到就去数据库查找,那么要把SIP弄垮真的是很容易,因此SIP对于Memcached中的数据认为是可信的,因此做Cluster(集群)也是必要的。

  1. 应用传入需要操作的key,通过CacheManager获取配置在Cluster中的客户端。
  2. 当获得Cache Client以后,执行Cache操作。
  • 如果是读取操作,当不能命中时去集群其他Cache客户端获取数据,如果获取到数据,尝试写入到本次获得的Cache客户端,并返回结果。(达到数据恢复的作用)
  • 如果是更新操作,在本次获取得Cache客户端执行更新操作以后,立即返回,将更新集群其他机器命令提交给客户端的异步更新线程对列去异步执行。(由于如果是根据key来获取Cache,那么异步执行不会影响到此主键的查询操作)

存在的问题

如果是设置了Timeout的数据,那么在丢失以后被复制的过程中就会变成永久有效的内容。

越来越感觉到DB力不从心,在面对千万级用户量的应用时,DB面对平凡的curd,特别是查询的时候,早已不堪重负!如何解决高并发下数据的查询效率,在应用中显的越来越重要,好了废话不多说,首先介绍下magent。

magent:

magent是一款开源的Memcached代理服务器软件,其项目网址为:http://code.google.com/p/memagent/

环境部署:

  • 安装libevent,Memcache用到了libevent这个库用于Socket的处理,所以需要安装libevent,libevent的最新版本2.0.22
  • 本文隐藏内容 登陆 后才可以浏览

  • 安装memcached.
  • 本文隐藏内容 登陆 后才可以浏览

  • 启动、结束memcached(根据实际的情况进行修改)
  • 本文隐藏内容 登陆 后才可以浏览

    本文隐藏内容 登陆 后才可以浏览

    • 安装php的memcache的扩展(仅参考)

    本文隐藏内容 登陆 后才可以浏览

    本文隐藏内容 登陆 后才可以浏览

    备注:

    1. 由于是测试,所以我只安装一台memcached服务器,会在这个机器上使用不同的端口启动多个memcached,在生产环境中,有多少memcached服务器就按照上面的方法安装多少台(如果是云服务器,可以在安装好一台之后做成镜像,批量安装)。
    2. 在本试验中我将代理和memcached安装在同一个服务器上(优先使用php的扩展直接连接memcached,如果实在实现不了,再使用代理的方式)。
    • magent安装(目前最新的版本为0.6)
    • 本文隐藏内容 登陆 后才可以浏览

    • 启动magent(根据实际的情况进行修改)
    • 本文隐藏内容 登陆 后才可以浏览

      测试:

      1、分别在11211、11212、11213端口启动3个Memcached进程,在8888端口开启magent代理程序;
      2、11211、11212端口为主Memcached,11213端口为备份Memcached;
      3、连接上8888的magent,set key1和set key2,根据哈希算法,key1被写入11212和11213端口的Memcached,key2被写入11211和11213端口的Memcached;

      4、连接到8888端口的magent取数据,key1和key2的值都能被取出。

      5、当11211端口的Memcached死掉,连接到8888端口的magent取数据,数据都会取出来。不会影响业务。

      6、当11211端口的Memcached重启复活,连接到8888端口的magent取数据,key2的值无法取出。
      7、当11211、11212端口的Memcached死掉,连接到8888端口的magent取数据,数据会从11213端口的Memcached取出;
      8、当11211、11212端口的Memcached重启复活,连接到8888端口,magent会从11211或11212端口的Memcached取数据,由于这两台Memcached重启后无数据,因此magent取得的将是空值,尽管11213端口的Memcached还有数据(此问题尚待改进)。

      9、一旦出现单个主库断掉,那么这个主库中的数据也就没有了,也不要复活主库,否则一旦复活主库,会返回空的数据给用户。解决方法是将备份的一台Memcahce提升为主库(将备份的Memcache服务器的ip改为断掉的主库的ip,切忌不能再代理端重启代理来修改主库的ip),返回给客户端。或者干脆不处理,这样程序会从备份的数据库中取数据返回给客户端。这样不会影响到业务。如果很不幸,所有的主库同时死掉,那么将备份库提升为主库为用户提供访问,减轻后端存储数据库的压力,原来的主库变为备份的数据库,从后端的的mysql数据库中慢慢的积累缓存数据到备份数据库中。

      本文隐藏内容 登陆 后才可以浏览

      配置memcached与 magent:

      magent与memcached 是可以混搭的,不必死板的一个magent s-memcached s-memcached b-memcached

      上图此模型已经能够很好的解决一个节点,一组服务器的缓存数据服务。但是如果在北方网通架设了一组服务器,同时在南方电信又架设了另外一组服务器,那么这两组相对独立的节点之间如何做到数据的同步与共享,基于magent与memcached的解决方案如下:

       

      需要注意的是,两组magent的配置最好完全一致,比如:

      北方的magent配置为:magent s-memcached1 s-memcached2 b-memcached3

      那么南方的magent配置也为:magent s-memcached1 s-memcached2 b-memcached3

      其顺序都是一致的,因为magent在分配key到memcached上时只是简单的使用散列余数算法。

      当然如果你够懒,那么你可以直接连接备份magent,因为所有的数据上面都有。

      有个特别要注意的地方是:

      1. 其中一台Memcached死掉,从magent取数据,数据会从备份的Memcached取出,保证用户不受影响.
      2. Memcached重启复活,由于这两台Memcached重启后无数据,因此magent取得的将是空值,尽管备份Memcached还有数据。可采用定时维护服务器,恢复memcached。
      3. 如果Memcached死掉,备份机同时死掉,那么只能说明你够倒霉,此时此刻你或许能见到上帝。

       

      java客户端:

      推荐使用:xmemcached

      http://code.google.com/p/xmemcached/

       缓存与DB的同步:

      比较保险的做法是:查询的时候从缓存中取,add、updae、delete的时候同时操作缓存与DB。

      当然你也可以定时同步缓存与DB的数据,个人认为不同的业务应该有不同的选择!

      我在实际的应用中是同时使用这两种方式,比如用户个人信息之类的内容,就用定时同步的方式。

       搜索引擎+缓存+DB:

      这个主题比较大,可以分为:

      1。文件结构的存储代替DB持久化存储。

      2。缓存在搜索引擎中的使用–文本库与索引库的缓存实现。

      3。使用搜索引擎进行统一的数据查询。

      4。文件同步读写。

       

       

发表评论