我试图通过在多线程Java中实现它来理解Strong和Causal一致性的概念。我使用Vert.x框架编写了以下代码。我正在尝试实施以下内容:
强一致性
因果一致性
必须以相同的顺序在所有数据中心中看到每个键的所有PUT操作。
在任何时间点,可以在不同的数据中心并行执行不同的操作。也就是说,每次只锁定一个数据中心以进行每个键的操作。
GET操作会立即返回该值,即使它已过时也不会被阻止。
Vert.x服务器上的API
以下是Vert.x服务器将接收并必须实现的以下GET和PUT操作:
Vertx-DNS:8080/put?key=KEY&value=VALUE
此端点将接收需要存储在数据中心实例中的密钥值对
Vertx-DNS:8080/get?key=KEY&loc=LOCATION
此端点将接收Vertx服务器必须返回值的密钥。服务器必须返回该值作为对此请求的响应。数据中心1的位置值为1,数据中心2的位置值为3,数据中心3的位置值为。
KeyValueLib.PUT(String datacenterDNS, String key, String value) throws IOException
此API方法将指定键的值放在指定的数据中心实例中。
KeyValueLib.GET(String datacenterDNS, String key) throws IOException
此API方法从指定的数据中心返回指定键的值。
代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.TimeZone;
import java.util.Iterator;
import java.util.Collections;
import java.util.List;
import java.sql.Timestamp;
import org.vertx.java.core.Handler;
import org.vertx.java.core.MultiMap;
import org.vertx.java.core.http.HttpServer;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.core.http.RouteMatcher;
import org.vertx.java.platform.Verticle;
public class Coordinator extends Verticle {
//Default mode: Strongly consistent. Possible values are "strong" and "causal"
private static String consistencyType = "strong";
/**
* TODO: Set the values of the following variables to the DNS names of your
* three dataCenter instances
*/
private static final String dataCenter1 = "ec2-52-2-18-9.compute-1.amazonaws.com";
private static final String dataCenter2 = "ec2-52-2-12-29.compute-1.amazonaws.com";
private static final String dataCenter3 = "ec2-52-2-10-12.compute-1.amazonaws.com";
@Override
public void start() {
//DO NOT MODIFY THIS
KeyValueLib.dataCenters.put(dataCenter1, 1);
KeyValueLib.dataCenters.put(dataCenter2, 2);
KeyValueLib.dataCenters.put(dataCenter3, 3);
final RouteMatcher routeMatcher = new RouteMatcher();
final HttpServer server = vertx.createHttpServer();
server.setAcceptBacklog(32767);
server.setUsePooledBuffers(true);
server.setReceiveBufferSize(4 * 1024);
routeMatcher.get("/put", new Handler<HttpServerRequest>() {
@Override
public void handle(final HttpServerRequest req) {
MultiMap map = req.params();
final String key = map.get("key");
final String value = map.get("value");
//You may use the following timestamp for ordering requests
final String timestamp = new Timestamp(System.currentTimeMillis()
+ TimeZone.getTimeZone("EST").getRawOffset()).toString();
Thread t = new Thread(new Runnable() {
public void run() {
//TODO: Write code for PUT operation here.
//Each PUT operation is handled in a different thread.
//Use helper functions.
try{
switch(consistencyType) {
case "strong":
//Do
break;
case "causal":
//Do
break;
default: continue;
}
}
}
});
t.start();
req.response().end(); //Do not remove this
}
});
routeMatcher.get("/get", new Handler<HttpServerRequest>() {
@Override
public void handle(final HttpServerRequest req) {
MultiMap map = req.params();
final String key = map.get("key");
final String loc = map.get("loc");
//You may use the following timestamp for ordering requests
final String timestamp = new Timestamp(System.currentTimeMillis()
+ TimeZone.getTimeZone("EST").getRawOffset()).toString();
Thread t = new Thread(new Runnable() {
public void run() {
//TODO: Write code for GET operation here.
//Each GET operation is handled in a different thread.
//Highly recommended that you make use of helper functions.
req.response().end("0"); //Default response = 0
}
});
t.start();
}
});
routeMatcher.get("/consistency", new Handler<HttpServerRequest>() {
@Override
public void handle(final HttpServerRequest req) {
MultiMap map = req.params();
consistencyType = map.get("consistency");
req.response().end();
}
});
routeMatcher.noMatch(new Handler<HttpServerRequest>() {
@Override
public void handle(final HttpServerRequest req) {
req.response().putHeader("Content-Type", "text/html");
String response = "Not found.";
req.response().putHeader("Content-Length",
String.valueOf(response.length()));
req.response().end(response);
req.response().close();
}
});
server.requestHandler(routeMatcher);
server.listen(8001);
}
}
KeyValueLib.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
public class KeyValueLib {
public static HashMap<String, Integer> dataCenters = new HashMap();
private static String URLHandler(String string) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
try {
String string2;
URL uRL = new URL(string);
HttpURLConnection httpURLConnection = (HttpURLConnection) uRL
.openConnection();
if (httpURLConnection.getResponseCode() != 200) {
throw new IOException(httpURLConnection.getResponseMessage());
}
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(httpURLConnection.getInputStream()));
while ((string2 = bufferedReader.readLine()) != null) {
stringBuilder.append(string2);
}
bufferedReader.close();
httpURLConnection.disconnect();
} catch (MalformedURLException var2_3) {
var2_3.printStackTrace();
}
return stringBuilder.toString();
}
public static void PUT(String string, String string2, String string3)
throws IOException {
String string4 = String.format("http://%s:8001/put?key=%s&value=%s",
string, string2, string3);
String string5 = KeyValueLib.URLHandler(string4);
try {
switch (dataCenters.get(string)) {
case 1 : {
break;
}
case 2 : {
Thread.sleep(200);
break;
}
case 3 : {
Thread.sleep(800);
break;
}
}
} catch (InterruptedException var5_5) {
// empty catch block
}
if (!string5.equals("stored")) {
System.out.println("Some error happened");
}
}
public static String GET(String string, String string2) throws IOException {
String string3 = String.format("http://%s:8001/get?key=%s", string,
string2);
String string4 = KeyValueLib.URLHandler(string3);
return string4;
}
}
有人可以帮我解决这个问题吗?