使用Vert.x在Java中实现强和因果一致性

时间:2015-04-05 09:25:21

标签: java database multithreading locking mutex

我试图通过在多线程Java中实现它来理解Strong和Causal一致性的概念。我使用Vert.x框架编写了以下代码。我正在尝试实施以下内容:

强一致性

  1. 每个PUT(写入)请求在所有副本中都是原子的。
  2. 在任何时间点,每个密钥只能在数据中心实例上执行1个PUT请求。
  3. 如果正在处理相同密钥的PUT操作,则每个密钥的GET操作将被阻止。
  4. 数据中心的锁定将在关键级别完成,即多个键上的操作可以并行运行。
  5. 因果一致性

    1. 必须以相同的顺序在所有数据中心中看到每个键的所有PUT操作。

    2. 在任何时间点,可以在不同的数据中心并行执行不同的操作。也就是说,每次只锁定一个数据中心以进行每个键的操作。

    3. GET操作会立即返回该值,即使它已过时也不会被阻止。

    4. 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;
          }
      }
      

      有人可以帮我解决这个问题吗?

0 个答案:

没有答案
相关问题