2016-09-06 2 views
1

클러스터 내에서 핫스팟을 만들지 만 가져 오기 쿼리를 쉽게 만들 수있는 데이터 모델을 만드는 것이 괜찮습니까?카산드라 데이터 모델링 - 핫스팟을 선택하여 쿼리를보다 쉽게 ​​만들 수 있습니까?

독서 중, 나는 지금 Solr과 일하고 있지 않다는 것을 명심하고이 데이터에 액세스 할 빈도가 주어진다면 spark-sql을 사용하는 것이 적절할 것이라고 생각하지 않았다. 나는 이것을 순수한 카산드라로하고 싶습니다.

우리는 데이터가 클러스터 주위에 고르게 분산되도록 파티션 키로 UUID를 사용하여 모델링 된 트랜잭션을 가지고 있습니다. 우리의 액세스 패턴 중 하나는 UI가과 같이 쿼리 특정 사용자 및 날짜 범위에 대한 모든 기록을 얻을 것을 요구한다 : 내가 만든

select * from transactions_by_user_and_day where user_id = ? and created_date_time > ?; 

첫 번째 모델은 트랜잭션이 생성 된 USER_ID 및 CREATED_DATE (하루 사용, 항상 설정 자정까지)를 기본 키로 사용하십시오.

CREATE transactions_by_user_and_day (
    user_ id int, 
    created_date timestamp, 
    created_date_time timestamp, 
    transaction_id uuid, 
    PRIMARY KEY ((user_id, created_date), created_date_time) 
) WITH CLUSTERING ORDER BY (created_date_time DESC); 

이 표는 잘 수행되는 것 같습니다. PK의 일부로 created_date를 사용하면 핫스팟을 방지하기 위해 사용자를 클러스터에보다 균등하게 분산시킬 수 있습니다. 그러나 액세스 관점에서 볼 때 데이터 액세스 계층은 우리가 원하는대로 더 많은 작업을 수행합니다. 작업을 간소화하기 위해

select * from transactions_by_user_and_day where user_id = ? and created_date in (?, ?, …) and created_date_time > ?; 

데이터 액세스 계층에서 수행되는, 나는 생각했다 모델링 : 그것은 제공 범위의 모든 일을 가진 IN 문을 만들 필요 대신 날짜와보다 큼 연산자를 제공 끝 그래서 같은 데이터 : 상기 모델

CREATE transactions_by_user_and_day (
    user_id int, 
    created_date_time timestamp, 
    transaction_id uuid, 
    PRIMARY KEY ((user_global_id), created_date_time) 
) WITH CLUSTERING ORDER BY (created_date_time DESC); 

는 데이터 액세스 계층 산드 내의 특정 날짜 범위에있는 사용자 및 필터의 TRANSACTION_ID 년대를 가져올 수있다. 그러나 이로 인해 클러스터 내의 핫스팟이 발생할 수 있습니다. 수명이 길거나 볼륨이 큰 사용자는 행에 더 많은 열을 생성합니다. 우리는 데이터에 TTL을 제공하여 60 일보다 오래된 것이 떨어지게하려고합니다. 또한 데이터의 크기를 분석 한 결과, 가장 많은 양의 사용자에 대해 60 일 분량의 데이터가 2MB 미만인 것으로 나타났습니다. 수학을 할 때, 40,000 명의 사용자 (이 숫자는 크게 늘어나지 않음)가 3 노드 클러스터에 균등하게 분산되고 사용자 당 2MB의 데이터가 노드 당 최대 26GB를 초과한다고 가정하면 (13333.33 * 2)/1024). 현실적으로 V-Nodes를 사용하는 카산드라가 단일 노드에 모든 사용자를 배치하게하려면 많은 양의 사용자 중 1/3로 끝내지 않을 것입니다. 리소스 관점에서 볼 때, 저는 26GB가 아무것도 만들지도 깨지 않을 것이라고 생각합니다.

의견을 보내 주셔서 감사합니다.

답변

1

날짜 모델 1 : IN 절을 사용하는 대신 각 ID에 대한 쿼리를 개별적으로 수행하도록 데이터 액세스 계층을 변경해야합니다. 그게 왜 더 나은지 이해하려면이 페이지를 확인하십시오.

https://lostechies.com/ryansvihla/2014/09/22/cassandra-query-patterns-not-using-the-in-query-for-multiple-partitions/

데이터 모델 2 : 노드 당 데이터의 26기가바이트 같은 많은 것 같지 않지만, 2 메가 바이트 조금 큰 것 가져. 물론 이상한 사람이라면 문제가없는 것 같습니다. 모델을 테스트하기 위해 카산드라 스트레스 작업을 설정해보십시오. 파티션의 대부분이 2MB보다 작 으면 좋을 것입니다.

다른 솔루션 중 하나는 버켓과 함께 데이터 모델 2를 사용하는 것입니다. 이것은 버킷 룩업 테이블을 유지해야하기 때문에 쓰기에 더 많은 오버 헤드를 줄 것입니다. 이 접근법에 대해 더 자세히 설명해 줄 필요가 있다면 알려주십시오.

+0

감사합니다. @gsteiner. 나는 IN 절을 사용하는 문제가 그 방향에서 나를 가리켜 주셔서 감사 할 수 있다고 생각하지 않았습니다. 데이터 액세스 레이어를 사용하면 많은 쿼리가 여전히 부끄러움을 느끼고 있습니다. 우린 이상하게 보입니다. (오랫동안 이야기해온 관계형 세계 일 수도 있습니다.) 데이터로 스트레스 테스트를 해보고 그 결과가 어떻게되는지 알아 보겠습니다. 버킷 팅에 대해 더 많이 듣고 싶습니다. 나는 그것에 대해 조금 읽었고 데이터 액세스 레이어에서 몇 가지 쿼리를 실행하고 버킷을 가져 와서 쿼리해야합니다. – ammills01

+1

많은 쿼리를하고 싶지 않은 것은 매우 "관계형"입니다. Cassandra는 실제로 각 쿼리가 해당 쿼리에 가장 적합한 코디네이터 노드를 사용할 것이기 때문에 많은 쿼리로 더 잘 작동합니다. 그래도 버킷을 사용하면 여러 쿼리를 수행해야하지만 모델 1보다 쿼리가 적습니다. 버켓 크기에 따라 다릅니다. – gsteiner

관련 문제