PDA

View Full Version : Caching dữ liệu với Memcached trong Java [Giới thiệu về Memcached]



iamvtn
24-03-2012, 03:23 PM
Giới thiệu về Memcached


http://memcached.org/images/memcached_banner75.jpg

Memcached là một công cụ hỗ trợ data caching rất tốt và rất mạnh mẽ, và dĩ nhiên ưu điểm hàng đầu của nó là hoàn toàn miễn phí. Nó thường được sử dụng để tối ưu hóa việc tải dữ liệu từ cơ sở dữ liệu cho các ứng dụng trên nền web. Nó rất thích hợp để caching những dữ liệu được truy cập nhiều nhưng ít bị thay đổi (như phần profiles trong facebook chẳng hạn), nó giúp tăng tốc truy cập và giảm workload với database trong hệ thống. Ngoài ra Memcached cũng có điểm mạnh là hỗ trợ việc phân tán rất tốt, cho nên bạn có thể dễ dàng triển khai với nhiều server memcached.

Vào lúc đầu, hệ thống memcached được phát triển bởi Danga Interactive và dùng cho LiveJournal. Sau đó memcached trở nên phổ biến và được dùng trên rất nhiều các website lớn khác như Youtube, Wikipedia, Flickr, Twitter, Mixi ....

Đây cũng là một hệ thống bộ nhớ phân tán mà Facebook đã sử dụng như một caching layer giữa web servers và MySQL server. Facebook đã tối ưu hóa Memcached và các phần liên quan và xây dựng một hệ thống bao gồm hàng ngàn servers với hàng chục terabytes dữ liệu được cached tại mỗi thời điểm. Có thể coi đây là hệ thống Memcached lớn nhất thế giới tại thời điểm này.

Trang chủ của memcached: http://memcached.org/

Special thank Mr Đỗ Tiến Khang, my ex-Team leader, help me alot the experience and knowledge about Caching Data.

iamvtn
24-03-2012, 03:33 PM
Cách cài đặt Memcached

Bạn có thể tải memached tại trang chủ: http://memcached.org/
Ở đây tôi sẽ dùng phiên bản memcached 1.4.4

1. Cách cài đặt memcached trong Windows.


Download: memcached-win32-1.4.4-14.zip
Unzip và copy vào thư mục nào đấy trong ổ cứng (ví dụ c:\memcached)
Mở command line vào thư mục chứa memcached và gõ memcached.exe -d install
Để start memcached server bạn gõ: memcached.exe -d start
Mặc định thì port của memcached server là 11211

2. Cách cài đặt memcached trong Linux.
Trước hết cần cài đặt libevent:


shell> cd /usr/local/src
shell> wget http://www.monkey.org/%7Eprovos/libevent-2.0.11-stable.tar.gz
shell> tar xzvf libevent-2.0.11-stable.tar.gz
shell> cd libevent-2.0.11-stable
shell> ./configure --prefix=/usr/local
shell> make
shell> make install

Sau đó cài Memcached:


shell> cd /usr/local/src
shell> wget http://memcached.googlecode.com/files/memcached-1.4.4.tar.gz
shell> tar xzvf memcached-1.4.4.tar.gz
shell> cd memcached-1.4.4
shell> LDFLAGS='-Wl,--rpath /usr/local/lib' ./configure --prefix=/usr/local
shell> make
shell> make install

Kiểm tra memcache đã ok chưa:

shell> memcached -u root -d
Nếu không thông báo lỗi gì hết là ok.

Trời nắng đẹp quá, đặt hòn gạch ra ngoài tí tối về viết tiếp :D

iamvtn
24-03-2012, 06:52 PM
Caching dữ liệu với Memcached trong Java

OK, vậy là đã xong phần cài đặt. Giờ tôi xin trình bầy tiếp làm thế nào để thao tác với Memcached thông qua Java.

Đầu tiên bạn phải có một thư viện để giao tiếp với Memcached Server.
Có khá nhiều loại thư viện như XMemcached (http://code.google.com/p/xmemcached/), SpyMemcached (http://code.google.com/p/spymemcached/) hay Memcached Java Client (https://github.com/gwhalin/Memcached-Java-Client/)

Ở đây tôi sử dụng Memcached Java Client bạn có thể tải thư viện tại: https://github.com/gwhalin/Memcached-Java-Client/

Tôi tạo một Java project có tên là HelloMemcached, add to build path thư viện Memcached Java Client vào project
http://diendan.congdongcviet.com/attachment.php?attachmentid=8937&stc=1&d=1332588281

Tiếp theo tạo một properties có tên là memcached_server_config.properties để lưu các thông tin cấu hình của Memcached server có nôi dung như sau:


HOST=localhost:11211

WEIGHTS=3,3
MAINT_SLEEP=30
INIT_CONN=5
MIN_CONN=5
MAX_CONN=250
#MAX_IDLE= 1000 * 60 * 60 * 6
MAX_IDLE=21600000
MAINT_SLEEP=30
NAGLE=FALSE
SOCKET_TO=3000
SOCKET_CONNECT_TO=0

#memcached
COMPRESS_ENABLE=TRUE
#COMPRESS_THRESHOLD=64 * 1024
COMPRESS_THRESHOLD=65536


Tiếp theo tôi định nghĩa một Singleton Class có tên là ReadProperty tác dụng để đọc file dạng *.properties như sau



package com.iamvtn.memcached.utility;

import java.io.*;
import java.util.*;

public class ReadProperty {
private final static ReadProperty INSTANCE = new ReadProperty();

static public ReadProperty getInstance() {
return INSTANCE;
}

public String getValue(String filePatch, String key) {
try {
File f = new File(filePatch);
if (f.exists()) {
Properties pro = new Properties();
FileInputStream in = new FileInputStream(f);
pro.load(in);

String p = pro.getProperty(key);
return p;
} else {
System.out.println("File not found!");
return null;
}
} catch (IOException e) {
System.out.println(e.getMessage());
return null;
}
}
}


Vì sao tôi lại phải lưu các config về cấu hình của memcached server ra ngoài một file dạng *.properties, vì làm như vậy sau này rất dễ thay đổi cấu hình config mà không phải build lại hệ thống, tiện lợi không nào :D

Tiếp theo tôi sẽ tạo một Constant Class để chứa constants, ở đây là các constant cho memcached



package com.iamvtn.memcached.constant;

public class Constant {
// Constant for config file
static public String MEMCACHED_CONFIG_FILE = System.getProperty("configPath") + "/memcached_server_config.properties";

// Constant for memcached;
static public String HOST = "HOST";
static public String WEIGHTS = "WEIGHTS";
static public String INIT_CONN = "INIT_CONN";
static public String MIN_CONN = "MIN_CONN";
static public String MAX_CONN = "MAX_CONN";
static public String MAINT_SLEEP = "MAINT_SLEEP";
static public String NAGLE = "NAGLE";
static public String MAX_IDLE = "MAX_IDLE";
static public String SOCKET_TO = "SOCKET_TO";
static public String SOCKET_CONNECT_TO = "SOCKET_CONNECT_TO";
}


Chú ý dòng code sau:


static public String MEMCACHED_CONFIG_FILE = System.getProperty("configPath") + "/memcached_server_config.properties";

dòng code này sẽ lấy ra được vị trí file memcached_server_config.properties thông qua config path chính vì vậy trước khi chạy hệ thống bạn phải set config patch của project trỏ đến thư mục của file memcached_server_config.properties.

Cuối cùng tôi sẽ tạo một class chứa các thao tác với memcached như khởi tạo và kết nối đến Memcached server, các hàm set get hay delete một Object trong memcached.
Ở đây tôi sử dụng mẫu thiết kế Singleton Pattern cho Class này.


/*
* Create by iamvtn (03/24/2012)
*/

package com.iamvtn.memcached.lib;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
import com.iamvtn.memcached.constant.Constant;
import com.iamvtn.memcached.utility.ReadProperty;


// Singleton Pattern
public class MyMemcached {

private static MyMemcached INSTANCE;

private MemCachedClient mcc = new MemCachedClient();

static public MyMemcached getInstance() {
if(INSTANCE == null){
INSTANCE = new MyMemcached();
}
return INSTANCE;
}

String filePatch = Constant.MEMCACHED_CONFIG_FILE;
String HOST = ReadProperty.getInstance().getValue(filePatch, Constant.HOST);
String WEIGHTS = ReadProperty.getInstance().getValue(filePatch, Constant.WEIGHTS);
String INIT_CONN = ReadProperty.getInstance().getValue(filePatch, Constant.INIT_CONN);
String MIN_CONN = ReadProperty.getInstance().getValue(filePatch, Constant.MIN_CONN);
String MAX_CONN = ReadProperty.getInstance().getValue(filePatch, Constant.MAX_CONN);
String MAINT_SLEEP = ReadProperty.getInstance().getValue(filePatch, Constant.MAINT_SLEEP);
String NAGLE = ReadProperty.getInstance().getValue(filePatch, Constant.NAGLE);
String MAX_IDLE = ReadProperty.getInstance().getValue(filePatch, Constant.MAX_IDLE);
String SOCKET_TO = ReadProperty.getInstance().getValue(filePatch, Constant.SOCKET_TO);
String SOCKET_CONNECT_TO = ReadProperty.getInstance().getValue(filePatch, Constant.SOCKET_CONNECT_TO);

// Khởi tạo và kết nối đến Memcached server
private MyMemcached() {
SockIOPool pool = SockIOPool.getInstance();

pool.setServers( HOST.split(","));
pool.setWeights(getWeightsProperty(WEIGHTS) ); // 3,3
pool.setInitConn(Integer.parseInt(INIT_CONN) ); // 5
pool.setMinConn(Integer.parseInt(MIN_CONN) ); // 5
pool.setMaxConn(Integer.parseInt(MAX_CONN)); // 250
pool.setMaintSleep(Integer.parseInt(MAINT_SLEEP)); // 30
pool.setNagle(Boolean.parseBoolean(NAGLE)); // FALSE
pool.setMaxIdle(Long.parseLong(MAX_IDLE) ); // 21600000
pool.setSocketTO(Integer.parseInt(SOCKET_TO)); // 3000
pool.setSocketConnectTO(Integer.parseInt(SOCKET_CO NNECT_TO) ); // 0

pool.initialize();
}
// sử lý tách các weights ra set vào một mảng Integer
private Integer[] getWeightsProperty(String weights) {
String[] strWeights = WEIGHTS.split(",");
Integer[] IntWeights = new Integer[strWeights.length];

int i = 0;
for(String strWeight : strWeights){
IntWeights[i] = Integer.valueOf(strWeight);
i++;
}
return IntWeights;
}

//Hàm get một Object từ Memcached server thông qua key.
public Object get(String key) {
System.out.println(this.getClass().getName() + " get(key) : " + key);
Object obj = mcc.get(key);
if (obj == null) {
System.out.println(this.getClass().getName() + " get : Object NULL");
} else {
System.out.println(this.getClass().getName() + " get : " + obj.toString());
}
return obj;
}

//Hàm set một Object vào Memcached server
public void set(String key, Object value) {
System.out.println(this.getClass().getName() + " set(key) : " + key);
if (mcc.set(key, value)) {
System.out.println(this.getClass().getName() + " set key success");
} else {
System.out.println(this.getClass().getName() + " set key error");
}
}

//Hàm get một Object từ Memcached server thông qua key.
public void delete(String key) {
System.out.println(this.getClass().getName() + " delete(key) : " + key);
if (mcc.delete(key)) {
System.out.println(this.getClass().getName() + " delete key success");
} else {
System.out.println(this.getClass().getName() + " delete key error");
}
}

}


Memcached quản lý các Object theo dạng Key-Value store, cho nên mỗi Object trong memcached đều có một key, và key này là duy nhất. Cho nên bạn có thể thấy các hàm như get, set hay delete đều dựa theo key truyền vào.

Phù, cơm phát rồi tí hoàn thành nốt.

iamvtn
24-03-2012, 08:28 PM
Về cơ bản thì ta đã chuyển bị xong, giờ viết một cái client test cãi xem thế nào (:))

Tạo một lớp để test như sau:


package test;

import com.iamvtn.memcached.lib.MyMemcached;

public class memcachedTest {

public static void main(String[] args) {
useMyMemcached();;
}


public static void useMyMemcached(){

//Tạo key có giá trị là key1
String key = "key1";
//Lấy dữ liệu từ memcached với key như trên
Object hello = MyMemcached.getInstance().get(key);

// Kiểu tra xem dữ liệu lấy từ memcached đã tốn tại hay chưa
if(hello == null) {
// Nếu chưa thì ta thực hiện set dữ liệu vào memcached
MyMemcached.getInstance().set(key, "hello chao");
System.out.println("Caching : " + (String)MyMemcached.getInstance().get(key));
return;
} else {
// Nếu đã tồn tại dữ liệu rồi thì ta lấy dữ liệu trực tiếp từ memcached ra
System.out.println("Read to memcached : " + hello.toString());
}

}
}


Khi chạy lần đầu tiên thì dữ liệu chưa có trong memcached, chương trình sẽ thực hiện lưu dữ liệu và memcached rồi sẽ in ra thông báo sau:


com.iamvtn.memcached.lib.MyMemcached get(key) : key1
com.iamvtn.memcached.lib.MyMemcached get : Object NULL
com.iamvtn.memcached.lib.MyMemcached set(key) : key1
com.iamvtn.memcached.lib.MyMemcached set key success
com.iamvtn.memcached.lib.MyMemcached get(key) : key1
com.iamvtn.memcached.lib.MyMemcached get : hello chao
Caching : hello chao

Nếu chạy từ lần thứ 2 trở đi, dữ liệu sẽ được lấy trực tiếp từ Memcached mà không phải khởi tạo dữ liệu nữa, chương trình sẽ in ra thông báo sau:


com.iamvtn.memcached.lib.MyMemcached get(key) : key1
com.iamvtn.memcached.lib.MyMemcached get : hello chao
Read to memcached : hello chao


Tải full mã nguồn tại file đính kèm

Thế là chúng ta đã thực hiện các thao tác rất cơ bản trên memcached như set hay get dữ liệu vào Memcached được rồi đấy :D. Cũng đơn giản phải không nào Y(:D. Thay vì viết như trên bạn cũng có thể thực hiện lấy dữ liệu từ Database rồi set vào Memcached :D, sau đó lại đọc từ memcached và không phải động vào DB nữa, lợi hại chưa nào Y(:D.

NHƯNG để áp dụng memcached vào hệ thống thực không phải là điều đơn giản, điều này tùy thuộc vào từng đặc điểm của các hệ thống khác nhau. Ví dụ như việc viết thuật toán tạo key như thế nào cho thật tối ưu cũng đủ đau đầu rồi, bạn cứ thử hình dung có hàng ngàn cách truy vấn vào các bảng dữ liệu từ DB mà dữ liệu trên DB lại không ngừng thay đổi (update, create, delete). Hay việc đồng bộ dữ liệu (synchronize) từ Memcached server với Database hay giữa các Memcached server với nhau cũng là điều cần phải tính toán thật cẩn thận nếu không thì việc sai sót về dữ liệu trả về là cực kỳ nguy hiểm ... Và có vân vân và mây mây việc cần phải tính toán để có một hệ thống memcached thật tốt.

manhdt
13-05-2012, 03:56 PM
Cảm ơn đại ka...Đã biết được thêm 1 vấn đề ^^

kidkid
17-05-2012, 10:36 PM
Hi Nam,
Dạo này thế nào rồi ? Vẫn còn code à ?

1. Cái cậu chạy trên windows là bản port của memcache ko phải của memcache gốc cậu nhé.


NHƯNG để áp dụng memcached vào hệ thống thực không phải là điều đơn giản, điều này tùy thuộc vào từng đặc điểm của các hệ thống khác nhau. Ví dụ như việc viết thuật toán tạo key như thế nào cho thật tối ưu cũng đủ đau đầu rồi, bạn cứ thử hình dung có hàng ngàn cách truy vấn vào các bảng dữ liệu từ DB mà dữ liệu trên DB lại không ngừng thay đổi (update, create, delete). Hay việc đồng bộ dữ liệu (synchronize) từ Memcached server với Database hay giữa các Memcached server với nhau cũng là điều cần phải tính toán thật cẩn thận nếu không thì việc sai sót về dữ liệu trả về là cực kỳ nguy hiểm ... Và có vân vân và mây mây việc cần phải tính toán để có một hệ thống memcached thật tốt.

1. Thuật toán tạo key ? Không quan trọng lắm. Key chỉ cần đủ cho hệ thống của cậu chạy là được. Đối với memcache điều đó không quan trọng.
2. Memcache ko liên quan đến syn & async với db. đó là cách của cậu. cậu có thể cache nguyên 1 sql query ( nếu cậu dùng db là sql) hoặc key (nếu là nosql) cơ mà ? Việc sync xuống có thể do 1 thread pool làm việc.
3. Hay nhất của memcache theo mình là hệ thống distribute mà nó nói, mình chưa làm nên ko chắc nhưng theo cách nó ghi trong wiki thì rất hay.


1 câu hỏi cho cậu ? Việc truyền giữ liệu giữa client - server theo dạng nào ? Benmark nó như thế nào ?

btw, cũng nên bỏ code thôi cậu :)

iamvtn
22-05-2012, 03:47 PM
Hi Nam,
Dạo này thế nào rồi ? Vẫn còn code à ?

btw, cũng nên bỏ code thôi cậu :)

Chào người anh em, lâu quá rồi nhỉ.
Ngoài lúc ốm ra lúc nào tớ cũng khỏe.
Có lẽ áp lực công việc đã khiến cậu mệt mỏi và chán code rồi ư? Coding nó là một công việc cậu ạ, mà công việc là công cụ giúp chúng ta sống, và đừng để công việc chi phối cuộc sống của cậu. Cơ mà phần lớn thời gian trong đời là ta dùng để làm việc, nếu làm một công việc mà cậu yêu thích thì cậu là một người hạnh phúc, còn nếu không thì cứ coi nó là công cụ để cậu thực hiện những gì mà cậu muốn. Ví dụ như tớ coding là đơn giản nó là cái giúp tớ có cái gì đó để làm hàng ngày, để tớ kiếm $ để sống và để làm những gì mà tớ thực sự yêu thích (đi phượt, trải nghiệm những điều mới mẻ)... Sống đơn giản cho đời thanh thản cậu ạ :D.



1. Cái cậu chạy trên windows là bản port của memcache ko phải của memcache gốc cậu nhé.

Bên trên tớ cũng có hướng dẫn cài đặt memcached cho Linux đó.



1. Thuật toán tạo key ? Không quan trọng lắm. Key chỉ cần đủ cho hệ thống của cậu chạy là được. Đối với memcache điều đó không quan trọng.

Thuật toán tạo key là rất quan trọng trong hệ thống sử dụng memcached, vì sao thì khi cậu thực sự nghiêm túc nghiên cứu để áp dụng memcached cho hệ thống của cậu thì cậu sẽ hiểu ra điều đó.



2. Memcache ko liên quan đến syn & async với db. đó là cách của cậu. cậu có thể cache nguyên 1 sql query ( nếu cậu dùng db là sql) hoặc key (nếu là nosql) cơ mà ? Việc sync xuống có thể do 1 thread pool làm việc.

Tớ vẫn chưa hiểu ý tưởng của cậu ? Memcached đơn giản chỉ là một bản sao của DB, cho nên việc đồng bộ với DB là điều tối quan trọng.



1 câu hỏi cho cậu ? Việc truyền giữ liệu giữa client - server theo dạng nào ? Benmark nó như thế nào ?

Tớ không đọc kỹ thư viện để thao tác với memcached, nếu cậu muốn biết cậu có thể đọc nó.

kidkid
25-05-2012, 07:40 PM
hê hê, vẫn còn code nhưng sắp bỏ rồi bạn ạ.


2. Từ client gởi lên server thì key & value sẽ serialize ra chuỗi. Do đó key chỉ cần đủ cho unique là được. 3. Memcache & những cache khác thì không liên quan đến csdl cậu nhé, chúng ta chỉ cache 1 phần (những phần hay được request & tốn thời gian đọc) chứ không phải chúng ta cache hết db.
Sync hay Async là 1 chiến lược, việc cậu đồng bộ là quan trọng nhưng không phải là điều quan trọng nhất. Và thường chúng ta chỉ đồng bộ từ memcache xuống db mà thôi, những worker thread sẽ đảm nhiệm việc này do đó mình nghĩ không cần phải lo lắng thái quá.

Mình vẫn nghĩ đến distributed system giữa các memcached server là khó hơn cả. :)

minhtoantm
09-08-2012, 03:56 PM
Anh ơi, em inport zô eclipse rồi run thì nó báo lỗi "file not found!", e thử mà không fix được

chienmdht
01-11-2013, 02:55 PM
Hi bạn,
Mình muốn dùng lệnh command line trực tiếp trên server để ghi dữ liệu vào hoặc kiểm tra cached trên ý thì làm thế nào bạn nhỉ?
Giống như là mình cài 1 phần mềm lên và ko muốn code, chỉ muốn thử hiệu năng của DB trước, thì chèn, sửa, xóa,... bằng lệnh hay script đơn giản trc, rồi mình đưa lên code sau ý. Mình là dân DBA nên mình hem bit code, đọc bài của bạn nhìn code mình ko bắt trước đc. hic.
Cảm ơn bạn nhiều!

bichthuan538
22-11-2013, 03:08 PM
hê hê, vẫn còn code nhưng sắp bỏ rồi bạn ạ.


2. Từ client gởi lên server thì key & value sẽ serialize ra chuỗi. Do đó key chỉ cần đủ cho unique là được. 3. Memcache & những cache khác thì không liên quan đến csdl cậu nhé, chúng ta chỉ cache 1 phần (những phần hay được request & tốn thời gian đọc) chứ không phải chúng ta cache hết db.
Sync hay Async là 1 chiến lược, việc cậu đồng bộ là quan trọng nhưng không phải là điều quan trọng nhất. Và thường chúng ta chỉ đồng bộ từ memcache xuống db mà thôi, những worker thread sẽ đảm nhiệm việc này do đó mình nghĩ không cần phải lo lắng thái quá.

Mình vẫn nghĩ đến distributed system giữa các memcached server là khó hơn cả. :)

Chỗ đồng bộ từ Memcache xuống DB, mọi người cho em hỏi chút. Giả sử gặp tình huống thế này:
Thực hiện việc insert hoặc update --> lúc này dữ liệu được lưu vào Database rồi nhưng chưa synchronize với memcache
Sau đó thực hiện việc insert, delete hoặc update tiếp theo, nhưng hành động này bị lỗi --> Sẽ rollback Database --> Nếu thực hiện đồng bộ từ memcahce xuống Database, thì các dữ liệu insert/update ở bước trên sẽ bị mất. Vậy sẽ phải làm thế nào?
Em mới tìm hiểu về mấy vấn đề này được mấy ngày nên còn nhiều chỗ chưa năm được :(

kidkid
12-01-2014, 08:48 PM
Chỗ đồng bộ từ Memcache xuống DB, mọi người cho em hỏi chút. Giả sử gặp tình huống thế này:
Thực hiện việc insert hoặc update --> lúc này dữ liệu được lưu vào Database rồi nhưng chưa synchronize với memcache
Sau đó thực hiện việc insert, delete hoặc update tiếp theo, nhưng hành động này bị lỗi --> Sẽ rollback Database --> Nếu thực hiện đồng bộ từ memcahce xuống Database, thì các dữ liệu insert/update ở bước trên sẽ bị mất. Vậy sẽ phải làm thế nào?
Em mới tìm hiểu về mấy vấn đề này được mấy ngày nên còn nhiều chỗ chưa năm được :(

Em chú ý chỗ này nhé, Memcache (hay bất kì hệ thống caching nào) ko phải datastore, em dùng nó để tăng tốc độ đọc ko phải lưu trữ.

Trở lại vấn đề của e anh chia ra các trường hợp thế này cho e hiểu:

Case #1: Đọc dữ liệu
Client đọc dữ liệu từ cache, nếu ko có, đọc từ db, update lên cache.
Case #2: Update dữ liệu
Client update dữ liệu db, nếu thành công, update dữ liệu ở cache
Case #3: Xóa dữ liệu
Client xóa db, nếu thành công, xóa ở cache.

Đây là cơ chế đơn giản hay dùng nhất khi e làm việc với cache & db.

vandon89
21-02-2014, 11:16 AM
Dùng cái memcached này cũng hay, nhưng tùy từng bài toán có thể áp dụng hay không.

Mình thấy chủ yếu dùng trong trường hợp cần truy cập dữ liệu nhanh vì dữ liệu được lưu trực tiếp trên ram, dữ liệu hay được sử dụng tìm kiếm, hoặc abcxyz gì đó nhưng bị ít khi thay đổi.

hugobaoloc
29-09-2014, 11:04 AM
Bạn sửa trong file Constant.java

static public String MEMCACHED_CONFIG_FILE = "properties/memcached_server_config.properties";