2013-10-23 2 views
1

좋은 하루,위시리스트 및 그래프 데이터베이스와의 재고 일치가 가능합니까?

이 내 사용 사례입니다 : 각 사용자 항목의 위시리스트와 그들이 제공하는 항목의 목록을 가지고있다. 항목의 양은 명확한 숫자이며 사용자는 임의의 숫자 일 수 있습니다.

내 목표는 로그인 한 사용자에게 알고리즘을 기반으로 권장 목록 또는 위시리스트와 일치하는 인벤토리를 가진 사용자 목록을 제공하는 것입니다. 주의 사항은 위시리스트를 기반으로 가장 많이 제공되는 사용자가 맨 위에 오르고 내림차순으로 정렬하는 방식으로 결과를 정렬 할 수 있어야한다는 것입니다. 쿼리가 상품 가상 서버 사양을 사용하여 3 초 이내에 완료 될 수 있기를 바란다면이 방법을 페이지 매김 방식으로 제시 할 수 있어야합니다.

내 데이터에 단순화를 위해 각 사용자를 그의 위시리스트에있는 35 개의 고유 항목과 그의 인벤토리에있는 250 개의 고유 항목으로 제한한다고 가정 해 봅시다. 테스트 데이터의 경우 한도에 따라 임의의 위시리스트/인벤토리 수를 가진 50,000 명의 사용자를 입력했습니다. MySQL의 조인을 사용하여이를 매핑했으며이 테스트 데이터에서 약 7 백만 개의 관계를 가졌습니다. 호기심 때문에, 위시리스트에 35 개의 항목이있는 사용자의 ID를 사용하여 위시리스트와 인벤토리 테이블에 가입하여 데이터베이스를 쿼리했습니다. 관련된 모든 열에서 가장 최적화 된 쿼리 패턴과 인덱스를 사용하더라도 쿼리를 완료하는 데 Rackspace 가상 서버 (2GB RAM, 1vCPU)가 21 초가 소요되었습니다. 하드웨어가 병목 현상이 아니라는 것을 알기 위해 가정용 컴퓨터에서 쿼리를 시도했습니다.이 컴퓨터는 상용 서버보다 훨씬 빠르고 RAM이 많았으며 쿼리가 끝나기까지 8 초가 걸렸습니다. 내 의도 된 3 초 미만의 목표에서 벗어났습니다.

그래프 데이터베이스를 사용하기로 결정하기 전에 모든 것을 시도했는지 확인하기 위해 MongoDB에서 동일한 테스트를 수행했으며 내 일치 알고리즘을 적용 할 수있는 유일한 방법은 MapReduce를 사용하는 것입니다. 그것은 내 집 컴퓨터에서 3 초 동안 원격 서버에서 9 초 검색어로 이어졌습니다. MapReduce가 서버에 과도하게 부담을 주므로 동시에 500 명의 사용자가 동시에 쿼리를 수행한다고 상상해보십시오.

지금 알고리즘에 나는에 대해 이야기하고있다 :
  1. 사용자의 위시리스트에있는 모든 물건을 가지고 해당 항목을 제공하는 사용자의 목록을 얻을.
  2. 위시리스트에있는 항목과 일치하는 항목을 각 사용자에게 제공하십시오. 요청한 항목 이상을 제공하면 원하는 수량을 사용하십시오.
  3. 이 개수를 집계하고 일치하는 위시리스트의 최종 비율을 가져옵니다. 그래프를 설계하는이 방법으로 저를 이끌어

    # users 
    ------------ 
    uid | name 
    ------------ 
    1 | Ramon 
    2 | Mark 
    3 | Ralph 
    ------------ 
    
    # wishlist 
    -------------------------- 
    pkid | uid | item_id | qty 
    -------------------------- 
    1 | 1 | 1  | 2 
    2 | 1 | 2  | 5 
    3 | 1 | 3  | 1 
    -------------------------- 
    
    # offers 
    -------------------------- 
    pkid | uid | item_id | qty 
    -------------------------- 
    1 | 2 | 1  | 1 
    2 | 3 | 2  | 2 
    2 | 2 | 3  | 7 
    

    :

의 일부 샘플 데이터 보자

enter image description here

그래서 노드 Ramon부터 시작을 얻을 수있는 그래프를 통과 나를위한 제안이있는 다른 사용자.위의 데이터와

uid | item_id | wishlist_qty | offer_qty 
---------------------------------------- 
2 | 1  | 2   | 1 
2 | 3  | 1   | 1 # this should be 7 but we only need 1 
3 | 2  | 5   | 2 
---------------------------------------- 

, 우리가 지금 수행하여 사용자의 위시리스트의 가장이있는 사용자 공식화 할 수 있습니다 : sum(offer_qty)/sum(wishlist_qty)를 다음 순서이를 기반으로 사용자를 평가하여 예비 결과 이전의 집계에해야 다음 이처럼 우리에게 무언가를 줄 것이다 내림차순으로 결과 :

가 당신이 그것을 가지고
uid | percentage 
---------------- 
2 | 0.67 
3 | 0.4 
---------------- 

, 그건 내가 달성하고자하는 추천 알고리즘입니다. 저는 그래프 데이터베이스에 익숙하지 않아서 이것이 성취 할 수 있고 환경과 사용자가 원하는만큼 잘 수행 할 수 있다면 옳은 방향으로 찔러야합니다. 다른 제안이있는 경우 열 스토어와 같은 다른 종류의 데이터베이스를 사용하거나 데이터 모델을 변경하여이 유스 케이스 및 의도 된 환경에서 작동하도록 할 수는 있지만 자유롭게 제안 할 수 있지만 어떻게 작동하게 할 수 있는지 기재하십시오. 내 시나리오와.

필자는 프로그래밍 문제를 완벽하게 보여주기를 바랍니다. 귀하의 답변에 미리 감사드립니다. 그래프 데이터베이스가 더 잘 수행, 그것은 충분히 수행 할 것인지 여부 것인지 여부로 질문을 복용 라몬

+0

위대한 사용 사례 설명! 당신이 더 나은 (그리고 충분히 좋은) 성능을 그래프 데이터베이스에서 모델링 할 수 있는지 의문이 있습니까? 대답은 '그렇습니다. 그러나 나는 당신이 아마 그 이상을 기대하고 있다고 생각합니다. :) – jjaderberg

답변

1

는 대답은 확실히 예 아마도 예. 지금까지 시도한 것보다 확실히 성능이 좋을 것입니다. 데이터를 잘 모델링 한 상태에서 이미 문제가있는 것 같으면 요구 사항 내에서 충분히 성능을 발휘할 것입니다. Neo4j를 권하고 싶습니다. 네와 같은 추천 엔진을위한 탁월한 선택입니다. 나는 당신의 모델을 Neo4j Console으로 대표하여 찔렀다. 어떤 벤치 마크도 얻지는 못하지만, 그것이 작동하게 될 것 같은 느낌을 줄 것입니다.

+0

아주 좋은 대답인데, 머리에 못을 박았을 수도 있습니다. 나는 neo4j에서 테스트 데이터를 설정하고 발견 한 것을 다시보고 할 것입니다. 나는 내가 보는 한 가지 문제는 다른 사용자가 제공하는 90 %와 같은 것을 원하는 경우이다. 그러면 그것은 매우 큰 결과가 될 것입니다. neo4j는 그것을 통과 할 때 메모리에 모든 것을로드 할 것인가? 또는 한 번에 15 개 이상을 반복 할 수있는 커서를 얻을 수 있습니까 (페이지 매김을 생각해보십시오)? 그리고 커서는 이미 결과를 집계하고 정렬해야합니다. 나는 너무 많이 요구하지 않기를 바란다. :) – voldomazta

+0

마지막으로 모든 데이터를 그래프에로드하고 미세 조정 및 캐시 온난 처리를 수행했습니다. 이거 확실히 빠르다. 가장 많은 것을 원했던 사람 (35 명)이 살 수있는 사람이 약 40,000 명이 었는데 쿼리 0.7ms를 할 수 있습니다. 페이지 매김도 훌륭하게 작동합니다! 나는 당신이 그래프를위한 RAM을 가지고있는 한, 정말로 빠르다고 생각합니다. 나는 너에게 더 많은 엄지 손가락을 줄 수 있으면 좋겠다. :) – voldomazta