TrafficServer一致性Hash的实验分析

来源:互联网 发布:淘宝营销方案短信 编辑:程序博客网 时间:2024/04/24 05:23

转载至:http://blog.chinaunix.net/uid-23242010-id-93353.html

 我们通过以下方法对TrafficServer的一致性Hash的性能进行测试,我们使用一个ip列表来模拟共有多少台机器参与Cluster进行测试,通过将每一个节点依次加入Cluster,然后再依次退出Cluster,每次加入节点和退出节点会重新构建hash映射,通过计算新的hash映射空间中有多少虚拟节点映射到与原来不同的节点中去,来测试Hash函数的性能。以下给出测试函数。

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

#define CLUSTER_MAX_MACHINES 256
#define CLUSTER_HASH_TABLE_SIZE 32707

struct ClusterMachine
{
  unsigned int ip;
};

struct ClusterConfiguration
{
  int n_machines;
  ClusterMachine *machines[CLUSTER_MAX_MACHINES];
  unsigned char hash_table[CLUSTER_HASH_TABLE_SIZE];
};

inline unsigned int
next_rand(unsigned int *p)
{
  unsigned int seed = *p;
  seed = 1103515145 * seed + 12345;
  *= seed;
  return seed;
}

void
build_hash_table_machine(ClusterConfiguration * c)
{
  int left = CLUSTER_HASH_TABLE_SIZE;
  int m = 0;
  int i = 0;
  unsigned int rnd[CLUSTER_MAX_MACHINES];
  unsigned int mach[CLUSTER_MAX_MACHINES];
  int total = CLUSTER_HASH_TABLE_SIZE;

  for (= 0; i < c->n_machines; i++) {
    int mine = total / (c->n_machines - i);
    mach[i] = mine;
    total -= mine;
  }

  for (= 0; m < c->n_machines; m++)
    rnd[m] = (((c->machines[m]->ip >> 15) & 0x7FFF) ^ (c->machines[m]->ip & 0x7FFF))
      ^ (c->machines[m]->ip >> 30);

  for (= 0; i < CLUSTER_HASH_TABLE_SIZE; i++)
    c->hash_table[i] = 255;

  m = 0;
  while (left) {
    do {
      i = next_rand(&rnd[m]) % CLUSTER_HASH_TABLE_SIZE;
    } while (c->hash_table[i] != 255);
    mach[m]--;
    c->hash_table[i] = m;
    left--;
    m = (+ 1) % c->n_machines;
  }
}

void
configuration_add_machine(ClusterConfiguration * cc, Machine * m)
{
  int i = 0;
  for (= 0; i < cc->n_machines; i++) {
    if (cc->machines[i]->ip > m->ip)
      break;
  }

  for (int j = cc->n_machines - 1; j >= i; j--)
    cc->machines[+ 1] = cc->machines[j];
  cc->machines[i] = m;
  cc->n_machines++;

  build_hash_table_machine(cc);
}

void
configuration_remove_machine(ClusterConfiguration * cc, Machine * m)
{
  printf("remove machines = %u\n", m->ip);
  for (int i = 0; i < cc->n_machines - 1; i++)
    if (== cc->machines[i])
      m = cc->machines[i] = cc->machines[+ 1];
  cc->n_machines--;

  build_hash_table_machine(cc);
}

int
main(int argc, char **argv)
{
  ClusterConfiguration mycc;
  mycc.n_machines=0;
  ClusterMachine *mymach;
  unsigned int fail;
  for (int i = 0; i < CLUSTER_HASH_TABLE_SIZE; i++)
    mycc.hash_table[i]=255;

  for(int i = 1; i < argc; i++) {
//printf("arg%d = %s\n", i, argv[i]);
    mymach=new Machine;
    mymach->ip=inet_addr(argv[i]);
//printf("machine ip = %u\n", mymach.ip);
    configuration_add_machine(&mycc, mymach);
    //printf("n_machines = %u\n", mycc.n_machines);
  }

  ClusterConfiguration newcc=mycc;
  for(int i = 0; i < mycc.n_machines; i++) {
    printf("n_machines = %u\n", newcc.machines[i]->ip);
  }
  for(int i = 0; i < mycc.n_machines; i++) {
    newcc=mycc;
    configuration_remove_machine(&newcc, mycc.machines[i]);
    printf("n_machines = %u\n", newcc.n_machines);
    fail=0;
    for (int j = 0; j < CLUSTER_HASH_TABLE_SIZE; j++) {
      if( mycc.hash_table[j] != i ){
        if ( mycc.hash_table[j] < i ) {
          if ( mycc.hash_table[j] != newcc.hash_table[j] ) {
            fail++;
          }
        }
        else {
          if ( mycc.hash_table[j] != newcc.hash_table[j] +1) {
            fail++;
          }
        }
      }
    }
    printf("Machine %u fail= %u\n", mycc.machines[i]->ip, fail);
  }
return(0);
}

    下面给出的是测试结果,左边代表的是有多少台机器参与测试,右边给出的是有多少数据在重新构建hash时发生了迁移。性能测试由永豪(yonghao@taobao.com)完成,并将结果作为issue TS-412提交至apache上。
10 0.13%
32 0.62%
64 0.71%
128 0.83%
254 1.23%


0 0