Memcached 병렬 제어 CAS 프로 토 콜
Memcached 는 1.2.4 버 전에 서 CAS (Check and Set) 프로 토 콜 을 추가 하여 자바 가 병발 하 는 CAS (Compare and Swap) 원자 작업 과 유사 하 게 같은 item 이 여러 스 레 드 로 변경 되 는 과정의 병발 문 제 를 처리 합 니 다.
Memcached 에서 각 key 는 64 - bit 길이 의 long 형 유일한 수 치 를 연결 하여 이 key 가 value 에 대응 하 는 버 전 번 호 를 표시 합 니 다.이 수 치 는 Memcached server 에서 생 성 되 며 1 부터 같은 Memcached server 는 중복 되 지 않 습 니 다.두 가지 상황 에서 이 버 전의 수 치 는 1: 1 을 추가 하고 key - value 쌍 을 추가 합 니 다.2. 키 에 대응 하 는 value 값 을 업데이트 하 는 데 성 공 했 습 니 다.아 이 템 버 전 값 을 삭제 하면 줄 어 들 지 않 습 니 다.
예 를 들 면:
MemcachedClient client = new MemcachedClient();
client.set("fKey", "fValue");
// set, Memcached server fKey value , 548;
client.set("fKey", "sValue");
// set, fKey value 549;
CASValue casValue = client.gets("fKey");
// key cas value( Memcached client , , ), casValue.getValue = "sValue",casValue.getCas=549;
CAS 프로 토 콜 로 해결 한 문제
여러 개의 Memcached client 와 set 같은 key 장면 을 모 의 합 니 다.clientA 가 현재 key 의 value set 를 "x" 로 설정 하고 작업 에 성공 하려 면;clientB 는 현재 key 의 value 값 을 "x" 에서 set 를 "y" 로 덮어 씁 니 다. 이때 clientA 는 key 에 따라 value 를 가 져 올 때 "y" 를 얻 습 니 다. 이 값 을 사용 하지만 다른 스 레 드 에 의 해 수정 되 었 는 지 모 르 면 문제 가 발생 할 수 있 습 니 다.
CAS 협 의 는 이런 병발 수정 문 제 를 해결 했다.현재 key - value 에 대한 value 를 수정 하려 는 스 레 드 가 있 을 때 gets 방법 으로 item 의 버 전 번 호 를 받 습 니 다. 작업 이 완료 되 었 을 때 카 스 방법 으로 신중하게 변경 합 니 다. 로 컬 에서 item 작업 과정 에서 이 key - value 가 Memcached server 에서 다른 스 레 드 로 변경 되 었 다 면 이번 수정 (낙관적 잠 금 개념) 을 포기 합 니 다.
CASValue casValue = client.gets(key);
//*****
//
//*****
CASResponse response = client.cas(key, newValue, casValue);
// item casValue.getCas(), item 。 , , Memcached server , true false ( , )
병발 환경 에서 의 정확성 검증
테스트 장면: Memcached client (C +, 자바 클 라 이언 트 모두 가능) 2 개 를 사용 하여 같은 key 값 을 동시에 변경 합 니 다. 하 나 는 value 를 1 로 추가 하고 하 나 는 value 를 1 로 줄 입 니 다. 만약 에 한 작업 이 실패 하면 (이번 읽 기 에서 변경 하 는 과정 에서 다른 프로 세 스 가 값 을 수 정 했 기 때 문) 수 치 를 수정 하 는 작업 이 실 패 했 습 니 다. 1 또는 1 을 추가 하여 한 변수 에 잠시 저장 합 니 다.다음 에 성공 할 때 한꺼번에 더 하거나 빼 면 데이터 의 정확성 을 확보 할 수 있다.아래 에 제 가 선택 한 두 개의 클 라 이언 트 프로그램 은 각각 C + + 와 자바 프로그램 입 니 다. 물론 두 개 모두 C + 와 자바 프로그램 도 마찬가지 입 니 다.
(memcached get () 방법 으로 데이터 포인 터 를 얻 은 후 메모리 방출 을 기억 하 십시오. 그렇지 않 으 면 메모리 유출 이 발생 할 수 있 습 니 다.http://docs.libmemcached.org/memcached_get.html)
//============================================================================
// Name : memcached_cpp.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C, Ansi-style
//============================================================================
#include <libmemcached/memcached.h>
#include <vector>
#include <sys/msg.h>
#include <errno.h>
#include <string>
#include <iostream>
#include <sys/file.h>
#include <stdio.h>
#include <vector>
#include <sys/time.h>
#include<time.h>
#include <math.h>
#include<sstream>
using namespace std;
int q2alen=0;
int alertfd=0;
string numberToString(int d){
std::stringstream ss;
ss<<d;
string str = ss.str();
return str;
}
/*
* @author: roger
* @version: 2014-05-17 17:45:10
*
*libmemcached , , ,
*/
int main() {
memcached_st *memc;
memcached_return rc;
memcached_server_st *server;
time_t expiration = 0 ; // 0
uint32_t flags =32 ; // java , 32
memc = memcached_create(NULL);
server = memcached_server_list_append(NULL, "localhost", 11211, &rc);
rc = memcached_server_push(memc, server); //set,get
memcached_server_list_free(server);
string value = "2";
size_t value_length = value.length(); //get value , 0
size_t key_length ;
rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
int num=1;
string key = "dai";
int i =0;
while(i<10000){
char * val = memcached_get(memc, key.c_str(), key.length(), &value_length,&flags, &rc);
// cout<<memc->result.item_cas<<endl;
int a = atoi(val);
a = a-num;
string val2 = numberToString(a);
rc = memcached_cas(memc, key.c_str(), key.length(), val2.c_str(),val2.length(), expiration, flags,memc->result.item_cas);
if (rc != MEMCACHED_SUCCESS) {
num++; // , 2 ,
}
else{
num = 1;// , 1
}
i++;
}
// free, , , memcached
memcached_free(memc);
return 0;
}
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
import com.schooner.MemCached.MemcachedItem;
public class test2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MemCachedClient client=new MemCachedClient();
String [] addr ={"localhost:11211"}; //ip、
Integer [] weights = {3};
//SockIOPool Memcached
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(addr);
pool.setWeights(weights);
pool.setInitConn(5);
pool.setMinConn(5);
pool.setMaxConn(200);
pool.setMaxIdle(1000*60*60);
pool.setMaintSleep(30);
pool.setNagle(false);
pool.setSocketTO(30);
pool.setSocketConnectTO(0);
pool.initialize();
// client.set("dai", "0"); //
// int result = (Integer) client.get("dai"); //
// System.out.println(result);
int num = 1; // 1
int a =0;
while (a<10000) {
MemcachedItem item = client.gets("dai");
String value = (String) item.getValue();
long cas = item.getCasUnique();
int value2 = Integer.valueOf(value)+num;
boolean issuccess =client.cas("dai", String.valueOf(value2), cas);
if (!issuccess) {
num++; // , 2 ,
}
else {
num = 1; // , 1
}
a++;
}
}
}
두 프로그램 이 동시에 실 행 됩 니 다. 중간 에 겹 치 는 부분 은 동시에 value 를 수정 하 는 부분 이자 우리 가 테스트 하 는 곳 입 니 다. 실행 이 끝 난 후에 memcached 의 값 이 0 인 것 을 발견 하면 병행 제어 에 성공 한 것 을 나타 냅 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.