搭建一个三台服务器的Memcached集群

关于memcached的基础知识可以查看博客其他博文,这里只记录了搭建的过程,谢谢!

1、分别在三台服务器上安装Memcached并启动

  第一、由于memcached是基于libevent的事件处理,所以需要安装libevent

yum install libevent libevent-devel

  第二、上传Memcached到三台服务器(192.168.176.129/192.168.176.130/192.168.176.131)解压并安装

tar -zxvf memcached-1.2.5.tar.gz
cd memcached-1.2.5
./configure
make
make install

默认情况下安装到/usr/local/bin下

  第三、启动三台服务器的memcached服务

/usr/local/bin/memcached -u root -p 1211 -m 64m -vv

-vv:用very vrebose模式启动,调试信息和错误输出到控制台
-d:座位deamon在后台启动
-d选项是启动一个守护进程,
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,
-u是运行Memcache的用户,我这里是root,
-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid,

2、编写客户端代码

  虽然Memcached是分布式的,但是本身是不支持的,我们需要在客户端编写分布式策略,具体代码里面注释写的非常详细

/**
 *
 */
package com.benxq.test;

import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;

import com.whalin.MemCached.MemCachedClient;
import com.whalin.MemCached.SockIOPool;

/**
 * @ClassName: MemcachedUtils
 * @Description: Memcached工具类
 * Created by qucf on 2016年1月14日.
 */
public class MemcachedUtils {

    private static final Logger logger = Logger.getLogger(MemcachedUtils.class);

    //如果多个memcached必须制定memcachedName
    private static SockIOPool sockIOPool=SockIOPool.getInstance("memcached1");

    //服务器列表 格式:127.0.0.1:port
    private static String[] servers=new String[]{"192.168.176.131:1211","192.168.176.129:1211"};
    //服务器权重  所有权重的最大公约数应该是1  否则会造成资源浪费
    private static Integer[] serverWeights=new Integer[]{1,1};

    private static MemCachedClient cachedClient;

    static {

        //设置服务器列表
        sockIOPool.setServers(servers);

        //设置服务器的权重  权重和服务器的位置一一对应
        sockIOPool.setWeights(serverWeights);

        //设置开始时每个cache服务器的可用连接数
        sockIOPool.setInitConn(2);

        //设置每个服务器最少可用连接数
        sockIOPool.setMinConn(2);

        //设置每个服务器最大可用连接数
        sockIOPool.setMaxConn(10);

        //设置可用连接池的最长等待时间  ms
        sockIOPool.setMaxIdle(5000);

        /**
         *设置连接池维护线程的睡眠时间
         *设置为0,维护线程不启动
         *维护线程主要通过log输出socket的运行状况,监测连接数目及空闲等待时间等参数以控制连接创建和关闭。
         */
        sockIOPool.setMaintSleep(0);

        //设置是否使用Nagle算法,因为我们的通讯数据量通常都比较大(相对TCP控制数据)而且要求响应及时,因此该值需要设置为false(默认是true)
        sockIOPool.setNagle(true);

        //设置socket的读取等待超时值 ms
        sockIOPool.setSocketTO(3000);

        //设置socket的连接等待超时值  ms
        sockIOPool.setSocketConnectTO(2000);

        /**
         *设置连接心跳监测开关。
         *设为true则每次通信都要进行连接是否有效的监测,造成通信次数倍增,加大网络负载,因此该参数应该在对HA要求比较高的场合设为TRUE,默认状态是false。
         */
        sockIOPool.setAliveCheck(false);

        /**
         *设置连接失败恢复开关
         *设置为TRUE,当宕机的服务器启动或中断的网络连接后,这个socket连接还可继续使用,否则将不再使用,默认状态是true,建议保持默认。
         */
        sockIOPool.setFailback(true);

        /**
         *设置容错开关
         *设置为TRUE,当当前socket不可用时,程序会自动查找可用连接并返回,否则返回NULL,默认状态是true,建议保持默认。
         */
        sockIOPool.setFailover(true);

        /**
          *设置hash算法
         *        alg=0 使用String.hashCode()获得hash code,该方法依赖JDK,可能和其他客户端不兼容,建议不使用
         *      alg=1 使用original 兼容hash算法,兼容其他客户端
         *       alg=2 使用CRC32兼容hash算法,兼容其他客户端,性能优于original算法
         *       alg=3 使用MD5 hash算法
         *采用前三种hash算法的时候,查找cache服务器使用余数方法。采用最后一种hash算法查找cache服务时使用consistent方法。
         */
        sockIOPool.setHashingAlg(3);

        //设置完pool参数后最后调用该方法,启动pool。
        sockIOPool.initialize();

        if (cachedClient == null){

            cachedClient = new MemCachedClient("memcached1");
            /**
             *设定是否压缩放入cache中的数据
             *默认值是ture
             *如果设定该值为true,需要设定CompressThreshold?
             */
            cachedClient.setCompressEnable(true);

            // 设定需要压缩的cache数据的阈值 默认值是30k
            cachedClient.setCompressThreshold(30);

            /*设置cache数据的原始类型是String
                默认值是false
                只有在确定cache的数据类型是string的情况下才设为true,这样可以加快处理速度。
             */
            cachedClient.setPrimitiveAsString(false);

        }
    }

    private MemcachedUtils() {
    }

    /**
     * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
     * @param key 键
     * @param value  值
     * @return
     */
    public static boolean set(String key, Object value) {
        return setExp(key, value, null);
    }

    /**
     * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
     * @param key 键
     * @param value 值
     * @param expire 过期时间 New Date(1000*10):十秒后过期
     * @return
     */
    public static boolean set(String key, Object value, Date expire) {
        return setExp(key, value, expire);
    }

    /**
     * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
     * @param key 键
     * @param value 值
     * @param expire 过期时间 New Date(1000*10):十秒后过期
     * @return
     */

    private static boolean setExp(String key, Object value, Date expire) {

        boolean flag = false;
        try {
            flag = cachedClient.set(key, value, expire);
        } catch (Exception e) {
            // 记录Memcached日志
            logger.error("Memcached set方法报错,key值:" + key + "\r\n");
        }
        return flag;
    }

    /**
     *
     * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。
     * @param key 键
     * @param value  值
     * @return
     */
    public static boolean add(String key, Object value) {
        return addExp(key, value, null);
    }

    /**
     * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。
     * @param key 键
     * @param value 值
     * @param expire 过期时间 New Date(1000*10):十秒后过期
     * @return
     */
    public static boolean add(String key, Object value, Date expire) {
        return addExp(key, value, expire);
    }

    /**
     * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。
     * @param key  键
     * @param value  值
     * @param expire  过期时间 New Date(1000*10):十秒后过期
     * @return
     */
    private static boolean addExp(String key, Object value, Date expire) {
        boolean flag = false;
        try {
            flag = cachedClient.add(key, value, expire);
        } catch (Exception e) {
            // 记录Memcached日志
            logger.error("Memcached add方法报错,key值:" + key + "\r\n");
        }
        return flag;
    }

    /**
     * 仅当键已经存在时,replace 命令才会替换缓存中的键。
     * @param key 键
     * @param value 值
     * @return
     */
    public static boolean replace(String key, Object value) {
        return replaceExp(key, value, null);
    }

    /**
     * 仅当键已经存在时,replace 命令才会替换缓存中的键。
     * @param key 键
     * @param value 值
     * @param expire 过期时间 New Date(1000*10):十秒后过期
     * @return
     */

    public static boolean replace(String key, Object value, Date expire) {
        return replaceExp(key, value, expire);
    }

    /**
     * 仅当键已经存在时,replace 命令才会替换缓存中的键。
     * @param key 键
     * @param value  值
     * @param expire 过期时间 New Date(1000*10):十秒后过期
     * @return
     */
    private static boolean replaceExp(String key, Object value, Date expire) {
        boolean flag = false;
        try {
            flag = cachedClient.replace(key, value, expire);
        } catch (Exception e) {
            logger.error("Memcached replace方法报错,key值:" + key + "\r\n");
        }
        return flag;
    }

    /**
     * get 命令用于检索与之前添加的键值对相关的值。
     * @param key  键
     * @return
     */
    public static Object get(String key) {
        Object obj = null;
        try {
            obj = cachedClient.get(key);
        } catch (Exception e) {
            logger.error("Memcached get方法报错,key值:" + key + "\r\n");
        }
        return obj;
    }

    /**
     * 删除 memcached 中的任何现有值。
     * @param key 键
     * @return
     */
    public static boolean delete(String key) {
        return deleteExp(key, null);
    }

    /**
     * 删除 memcached 中的任何现有值。
     * @param key   键
     * @param expire 过期时间 New Date(1000*10):十秒后过期
     * @return
     */
    public static boolean delete(String key, Date expire) {
        return deleteExp(key, expire);
    }

    /**
     * 删除 memcached 中的任何现有值。
     * @param key 键
     * @param expire  过期时间 New Date(1000*10):十秒后过期
     * @return
     */
    private static boolean deleteExp(String key, Date expire) {
        boolean flag = false;
        try {
            flag = cachedClient.delete(key, expire);
        } catch (Exception e) {
            logger.error("Memcached delete方法报错,key值:" + key + "\r\n");
        }
        return flag;
    }

    /**
     * 清理缓存中的所有键/值对
     * @return
     */
    public static boolean flashAll() {
        boolean flag = false;
        try {
            flag = cachedClient.flushAll();
        } catch (Exception e) {
            logger.error("Memcached flashAll方法报错\r\n");
        }
        return flag;
    }

    public static void main(String[] args) {
        MemcachedUtils.add("teacher", "zhangsan");
//        Object obj = MemcachedUtils.get("room");
//        System.out.println("===="+obj+"====");
    }
}

如有问题,大家可以联系我QQ 752432995 一同交流技术分享学习的快乐!

时间: 2024-10-11 15:13:21

搭建一个三台服务器的Memcached集群的相关文章

搭建一个分布式MongoDB鉴权集群

今天休假在家,测试并搭建了一个replica set shard MongoDB鉴权集群.replica set shard 鉴权集群中文资料比较少,本文是个人笔记,同时也希望对后来者有所帮助.本文仅是搭建步骤和Q&A,用于实际工作中的使用查阅,阅读者需要有分布式集群的理论基础. 关键字:Replica-Set Shard 副本 分片 鉴权 KeyFile auth MongoDB根据部署的不同,有两种添加鉴权的方式,分别是单实例的鉴权方式和KeyFile的鉴权方式.两种方式的共同点都是,先在没

Docker 搭建一个Elasticsearch 7.5.1集群+kibana 7.5.1

1.docker安装elasticsearch 7.5.1 拉取镜像 docker pull elasticsearch:7.5.1 创建网络 如果需要安装kibana等其他,需要创建一个网络,名字任意取,让他们在同一个网络,使得es和kibana通信 docker network create esnet(这个名字可以自定义,但是注意启动kibana是名字保持一致) 创建数据卷 此处为了docker容器删除或者其他异常情况,将ES的重要数据挂载到宿主机 # 查看当前数据局列表 docker v

(二)搭建一个完成的Kubernetes/K8s集群v.1.16

单节点集群多节点集群 注意node通过连接loadbalancer 转发到mateter 的apiserver来进行运作的 集群规划: 角色 ip 组件 K8S-master1 192.168.0.101 kube-apiserver kube-controller-manager kube-scheduleretcd K8S-master2 192.168.0.102 kube-apiserver kube-controller-manager kube-scheduleretcd K8S-n

Magent搭建Memcached集群

Magent搭建Memcached集群 Memcached集群介绍 由于Memcached服务器与服务器之间没有任何通讯,并且不进行任何数据复制备份,所以当任何服务器节点出现故障时,会出现单点故障,如果需要实现HA,则需要通过另外的方式来解决. 通过Magent缓存代理,防止单点现象,缓存代理也可以做备份,通过客户端连接到缓存代理服务器,缓存代理服务器连接缓存连接服务器,缓存代理服务器可以连接多台Memcached机器可以将每台Memcached机器进行数据同步.如果其中一台缓存服务器down机

Memcached集群/分布式/高可用 及 Magent缓存代理搭建过程 详解

当网站访问量达到一定时,如何做Memcached集群,又如何高可用,是接下来要讨论的问题. 有这么一段文字来描述“Memcached集群” Memcached如何处理容错的? 不处理!:) 在memcached节点失效的情况下,集群没有必要做任何容错处理.如果发生了节点失效,应对的措施完全取决于用户.节点失效时,下面列出几种方案供您选择: * 忽略它! 在失效节点被恢复或替换之前,还有很多其他节点可以应对节点失效带来的影响. * 把失效的节点从节点列表中移除.做这个操作千万要小心!在默认情况下(

Ubuntu 16.04通过Magent搭建Memcached集群(转)

一.下载Magent 官网:https://code.google.com/archive/p/memagent/downloads 离线版本:(链接: https://pan.baidu.com/s/1kU9DLI3 密码: k6qg) 二.编译安装 说明:magent由于是10年的产品,所以编译时一定会报错,但是先不要按照网上的修改来操作,应该先执行make,然后看错误来解决,因为每个系统的解决方式都不同,应该按照不同的系统来处理才是最优的解法. 前提:先安装Memcached,参考:htt

阿里云ECS服务器部署HADOOP集群(三):ZooKeeper 完全分布式集群搭建

本篇将在阿里云ECS服务器部署HADOOP集群(一):Hadoop完全分布式集群环境搭建的基础上搭建,多添加了一个 datanode 节点 . 1 节点环境介绍: 1.1 环境介绍: 服务器:三台阿里云ECS服务器:master, slave1, slave2 操作系统:CentOS 7.3 Hadoop:hadoop-2.7.3.tar.gz Java: jdk-8u77-linux-x64.tar.gz ZooKeeper: zookeeper-3.4.14.tar.gz 1.2 各节点角色

部署AlwaysOn第一步:搭建Windows服务器故障转移集群

在Windows Server 2012 R2 DataCenter 环境中搭建集群之前,首先要对Windows服务器故障转移集群(Windows Server Failover Cluster,简称WSFC)有基本的了解.WSFC必须部署在域管理环境中,由多台服务器组成,每台服务器称作一个"结点"(Node),每个结点上都运行了Windows服务器故障转移集群服务,整个集群系统允许部分结点掉线.故障或损坏而不影响整个系统的正常运作.集群自动检测结点的健康状态,一旦活跃结点发生异常,变

Linux下安装搭建Memcached集群环境

Linux下安装搭建Memcached集群环境