[ElasticSearch] Hash Partition 테스트

Elastic/Elasticsearch 2014. 8. 27. 14:15

간혹 특정 shard 로 색인 문서가 몰리는 경우가 있습니다.

이럴경우 _id 값에 대한 key 조합을 확인해야 할 필요가 있는데요.

es 내부에서 사용하는 hash 함수를 이용해서 간단하게 테스트 해볼수 있습니다.


[테스트 코드]

public class EsHashPartitionTest {

    private static final Logger log = LoggerFactory.getLogger(EsHashPartitionTest.class);

    private HashFunction hashFunction = new DjbHashFunction();

    


    @Test

    public void testHashPartition() {

        int shardSize = 120;

        List<Long> shards = new ArrayList<Long>();

        long[] partSize = new long[shardSize];

        

        for ( int i=0; i<shardSize; i++ ) {

            shards.add((long) 0);

            partSize[i] = 0;

        }

        

        for ( int i=0; i<1000000; i++ ) {

            int shardId = MathUtils.mod(hash(String.valueOf(i)), shardSize);

            shards.add(shardId, (long) ++partSize[shardId]);

        }

        

        for ( int i=0; i<shardSize; i++ ) {

            log.debug("["+i+"] {}", partSize[i]);

        }

    }

    

    public int hash(String routing) {

        return hashFunction.hash(routing);

    }

}


[Hash 함수 원본 코드]

/**

 * This class implements the efficient hash function

 * developed by <i>Daniel J. Bernstein</i>.

 */

public class DjbHashFunction implements HashFunction {


    public static int DJB_HASH(String value) {

        long hash = 5381;


        for (int i = 0; i < value.length(); i++) {

            hash = ((hash << 5) + hash) + value.charAt(i);

        }


        return (int) hash;

    }


    public static int DJB_HASH(byte[] value, int offset, int length) {

        long hash = 5381;


        final int end = offset + length;

        for (int i = offset; i < end; i++) {

            hash = ((hash << 5) + hash) + value[i];

        }


        return (int) hash;

    }


    @Override

    public int hash(String routing) {

        return DJB_HASH(routing);

    }


    @Override

    public int hash(String type, String id) {

        long hash = 5381;


        for (int i = 0; i < type.length(); i++) {

            hash = ((hash << 5) + hash) + type.charAt(i);

        }


        for (int i = 0; i < id.length(); i++) {

            hash = ((hash << 5) + hash) + id.charAt(i);

        }


        return (int) hash;

    }

}

- https://github.com/elasticsearch/elasticsearch/tree/master/src/main/java/org/elasticsearch/cluster/routing/operation/hash


이와 관련된 자세한 내용은 아래 링크 참고하세요.

http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/routing-value.html

: