Java-191 Netflix EVCache Client 接入 Memcached 实战:安装、配备与踩坑记录
TL;DR
- 场景:Java 应用想在本地或小团队环境体验 Netflix EVCache,但服务端未开源,只能基于 Memcached 自建。
- 结论:通过源码编译 Memcached 1.6.39,并按 EVCache 的节点配置规范启动,就能完成基本读写与链路验证。
- 产出:给出从编译安装 Memcached、启动参数说明,到 EVCache Client POM 依赖与示例代码的一条龙配置指引。

版本矩阵
| 组件/环境 | 版本/说明 | 已验证 | 说明 |
|---|---|---|---|
| Memcached | 1.6.39 | 是 | 按文中步骤在 Linux 环境下载源码、./configure 编译并安装。 |
| libevent | 系统仓库默认(yum 安装) | 是 | 通过 yum install libevent libevent-devel gcc-c++ 获取。 |
| EVCache Client | 4.139.0 | 是 | 作为核心客户端依赖,负责与 Memcached 通信与封装。 |
| spymemcached | 2.12.3 | 是 | EVCache 底层 Memcached 客户端实现,需与服务端协议兼容。 |
| Eureka Client | 1.5.6(runtime) | 是 | 文中作为依赖引入,当前示例中主要满足 EVCache 依赖链。 |
| Spectator | 0.80.1 | 是 | 用于指标采集与监控,示例中作为运行时组件引入。 |
| Archaius / Archaius2 | 0.6.0 / 2.3.13 | 是 | 动态配置组件,满足 EVCache 配置体系依赖。 |
安装使用
由于Netflix没有开源 EVCache的服务器部分,这里采用 Memcached 作为服务器。
Memcached 介绍
Memcached 是一个开源的、高性能的分布式内存对象缓存系统,主要用于减轻数据库负载,提升动态 Web 应用的访问速度。它通过在内存中缓存数据和对象来减少对数据库的直接访问次数,从而提高动态网站的性能。
核心特性
- 内存存储:所有数据都存储在内存中,读写速度极快(通常在微秒级别完成操作)
- 键值存储:采用简单的键值对(key-value)存储结构
- 分布式架构:支持多服务器集群部署
- LRU 算法:当内存不足时,采用最近最少使用算法自动清除数据
工作原理
当应用程序需要数据时:
- 首先检查 Memcached 中是否存在该数据
- 如果存在(缓存命中),直接从内存返回结果
- 如果不存在(缓存未命中),则从数据库获取数据,并将结果存入 Memcached 供后续使用
典型应用场景
- 数据库查询缓存:缓存频繁访问的数据库查询结果
- 会话存储:存储用户会话信息
- API 缓存:缓存第三方 API 的响应结果
- 页面片段缓存:缓存动态页面的部分内容
优势与局限
优势:
- 极高的读写性能
- 简单的部署和使用
- 良好的水平扩展能力
- 降低数据库负载
局限:
- 数据不具备持久性(重启服务数据会丢失)
- 没有内置的安全机制(如认证)
- 缺乏数据同步和复制功能
基本命令示例
# 连接 Memcached
telnet localhost 11211
# 存储数据
set key 0 900 10
helloworld
# 获取数据
get key
Memcached 通常与 MySQL、PostgreSQL 等关系型数据库配合使用,是构建高性能 Web 应用的重要组件之一。
安装 Memcached
# 安装libevent库
yum install libevent libevent-devel gcc-c++
cd /opt/software
# 下载最新的memcached
wget http://memcached.org/latest
tar -zxvf latest

cd memcached-1.6.39
./configure --prefix=/usr/memcached
make
make install

./memcached -d -m 1000 -u root -l 0.0.0.0 -p 11211 -c 256 -P /tmp/memcached.pid
以下是扩展后的内容,增加了参数说明和使用示例:
-d 选项:以守护进程(daemon)模式启动Memcache服务,使服务在后台运行而不占用终端。例如:
memcached -d会立即返回shell提示符。-m 参数:设置分配给Memcache服务使用的内存总量,单位为MB。例如:
-m 64表示分配64MB内存。建议根据服务器可用内存合理配置,通常设置为总内存的10-30%。-u 参数:指定运行Memcache服务的系统用户。出于安全考虑,建议使用非root用户。例如:
-u nobody会以nobody用户身份运行服务。-l 参数:设置Memcache监听的服务器IP地址。默认监听所有可用网络接口(0.0.0.0)。例如:
-l 192.168.1.100只监听指定IP。-p 参数:配置Memcache服务监听的TCP端口号,默认是11211。例如:
-p 11211。如果修改默认端口,客户端连接时需指定相同端口。-c 参数:设置最大并发连接数,默认1024。在高并发场景下可能需要调高此值。例如:
-c 2048允许最多2048个并发连接。-P 参数:指定存储Memcache进程ID(pid)的文件路径。例如:
-P /var/run/memcached.pid。通过pid文件可以方便地管理服务进程。
典型启动示例:
memcached -d -m 256 -u memcache -l 192.168.1.100 -p 11211 -c 2048 -P /var/run/memcached.pid
这个命令会启动一个Memcache守护进程,分配256MB内存,以memcache用户身份运行,监听192.168.1.100的11211端口,允许2048个并发连接,并将进程ID保存在指定文件。

使用 EVCache Client
POM
<dependencies>
<dependency>
<groupId>com.netflix.evcache</groupId>
<artifactId>evcache-client</artifactId>
<version>4.139.0</version>
</dependency>
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<version>1.5.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.netflix.spectator</groupId>
<artifactId>spectator-nflx-plugin</artifactId>
<version>0.80.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.netflix.spectator</groupId>
<artifactId>spectator-api</artifactId>
<version>0.80.1</version>
</dependency>
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
<version>0.20.7</version>
</dependency>
<dependency>
<groupId>com.netflix.servo</groupId>
<artifactId>servo-core</artifactId>
<version>0.12.25</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.netflix.nebula</groupId>
<artifactId>nebula-core</artifactId>
<version>4.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius2-core</artifactId>
<version>2.3.13</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-aws</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.8</version>
</dependency>
</dependencies>
编写代码
package icu.wzk;
import com.netflix.evcache.EVCache;
public class CacheDemo01 {
public static void main(String[] args) throws Exception {
String server = "SERVERGROUP1=172.16.1.130:11211";
System.setProperty("EVCACHE_1.use.simple.node.list.provider", "true");
System.setProperty("EVCACHE_1-NODES", server);
EVCache evCache = new EVCache.Builder()
.setAppName("EVCACHE_1")
.build();
evCache.set("wzk", "icu", 10);
String data = evCache.get("wzk");
System.out.println(data);
}
}
测试运行代码如下:
错误速查
| 症状 | 根因 | 定位思路 | 修复方式 |
|---|---|---|---|
| Java 代码中 EVCache set 正常,get(“wzk”) 返回 null 或空 | key 过期时间过短,或拼写不一致,或 Memcached 未正确启动 | 通过 telnet host 11211 手动 get key,确认服务端是否有值且未过期 | 延长过期时间参数,统一 key 命名;确保 Memcached 已正常启动且无重启/杀进程 |
| 客户端启动时报 Connection refused 或超时 | -l 监听地址与客户端连接地址不一致,或端口被防火墙拦截 | 在服务端执行 `netstat -ntlp | grep 11211` 确认监听地址与端口;检查防火墙 |
| 使用文中命令启动 Memcached 报 permission denied | -P 指定的 pid 文件路径目录无写权限,或非 root 用户无权限 | 检查 /tmp/memcached.pid 或自定义路径的目录权限与所属用户 | 将 -P 指向有写权限的目录,或调整目录权限;生产中使用专门的非 root 用户与目录 |
| Memcached 启动后占用内存远高于预期 | -m 设置过大,或多实例叠加,或系统其他进程内存紧张 | 通过 `ps aux | grep memcached和top` 观察内存占用与参数 |
| 编译阶段 ./configure 或 make 报找不到 libevent 等错误 | 未安装 libevent-devel 或编译工具链不完整 | 检查 `yum list installed | grep libevent`,确认是否安装 -devel 包 |
| EVCache Client 运行时报依赖冲突或 NoSuchMethodError | 项目中已有不同版本的 rxjava/spectator 等依赖导致冲突 | 通过 mvn dependency:tree 排查同名依赖的版本,定位冲突来源 | 使用 Maven 依赖排除()或在父 POM 锁定统一版本,减少多版本并存 |
| 通过 telnet set/get 正常,但 Java 中读写报错或乱码 | 字符编码、序列化方式不一致,或客户端对 value 做了自定义处理 | 对比 telnet 与 Java 中的实际字节内容,检查序列化/编码设置 | 确保客户端与服务器统一使用 UTF-8 等约定编码;若有自定义序列化,要在文中提示读者注意 |
| 本地能连,跨机器连不上 Memcached | -l 绑定为 127.0.0.1,外部机器无法访问 | 在服务端确认 -l 参数值和监听 IP;用外部机器 telnet IP 11211 测试 | 将 -l 修改为内网 IP 或 0.0.0.0 并重启服务,必要时调整安全组与防火墙策略 |
其他系列
AI篇持续更新中(长期更新)
AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!
AI研究-132 Java 生态前沿 2025:Spring、Quarkus、GraalVM、CRaC 与云原生落地
AI模块直达链接
Java篇持续更新中(长期更新)
Java-180 Java 接入 FastDFS:自编译客户端与 Maven/Spring Boot 实战
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务已完结,Dubbo已完结,MySQL已完结,MongoDB已完结,Neo4j已完结,FastDFS 已完结,OSS正在更新… 深入浅出助你打牢基础!
Java模块直达链接
大数据板块已完成多项干货更新(300篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
大数据模块直达链接

浙公网安备 33010602011771号