2017-05-15 3 views
0

목록이 있으며 redis에 캐시하고 싶습니다. 나는 해시를 사용하여 그것을 달성하는 두 가지 방법을 시도했다.Redis의 목록 저장

이 첫 번째 방법을 고려하십시오. 나는 해시 값으로 하나의 해시 및 설정 항목을 만들 : 반복하려면

// .. 

$apiArray = [..]; // array from parsing an api 

if(!$c->keys('lista')){ 
    foreach (json_decode($apiArray) as $item){ 
     $c->hset('lista', $item->id, serialize($item)); 
    } 
} 

foreach ($c->hgetall('lista') as $key){ 

    $item = unserialize($key); 

    echo '<p>'; 
    echo '<strong>id</strong>: '.$item->id.'<br>'; 
    echo '<strong>name</strong>: '.$item->name.'<br>'; 
    echo '<strong>email</strong>: '.$item->email.'<br>'; 
    echo '</p>'; 
} 

10000 항목, 그것은 0.5 초 걸립니다.

이제 이것을 생각해보십시오. 원의 배열의 각 요소에 하나의 해쉬 :

if(!$c->keys('lista:*')){ 
    foreach (json_decode($apiArray) as $item){ 
     $c->hset('lista:'.$item->id, 'element', serialize($item)); 
    } 
} 

foreach ($c->keys('lista:*') as $item) { 
    $item = unserialize($c->hget($item, 'element')); 

    echo '<p>'; 
    echo '<strong>id</strong>: '.$item->id.'<br>'; 
    echo '<strong>name</strong>: '.$item->name.'<br>'; 
    echo '<strong>email</strong>: '.$item->email.'<br>'; 
    echo '</p>'; 
} 

10000 개 레코드 루프 3초 걸린다.

두 번째 방법은 Redis 공식 문서에서 다루는 접근법이며 zadd 및 sadd를 사용하여 보조 색인을 지원하기 때문에 매우 놀랍습니다.

왜 첫 번째 방법보다 느린가요? 내가 틀렸어?

루프에서 항목을 가져 오기 위해 hgetall() 메서드를 10000 번 호출해야하기 때문에 발생할 수 있다고 생각합니다. 이걸 믿을 수 있니?

첫 번째 접근 방식을 선호합니까?

너희들

M :

답변

2

코드의 두 번째 블록이 느린 이유는 루프의 각 반복에 대한 hget 호출을 것입니다 감사합니다. 따라서 반복 할 때마다 Redis 서버로 네트워크를 왕복합니다.

대조적으로 첫 번째 코드 블록은 루프 블록 내에서 네트워크 호출을하지 않습니다. 그래서 훨씬 더 빠르게 실행됩니다.

+0

감사합니다. 저에게 의미가 있습니다. 하지만 이제 질문은 : 루프에서 hget (또는 scan)을 호출하지 않도록 walkthrought이 있습니까? – Mauro

+1

배열의 각 요소에 해시를 생성하는 대신 문자열 값을 대신 사용할 수 있도록 데이터를 재구성 할 수 있습니까? 그런 다음 mget을 사용하여 여러 항목을 가져 와서 왕복을 줄일 수 있습니다. –

+0

또는 파이프 라이닝 사용 –

1

전체 목록을 캐싱 할 때마다 매번 대량으로 작성하고 가져 오는 것이 좋습니다. 이 경우 수행 할 수있는 작업은 최대한의 성능을 얻기 위해 전체 내용을 JSON으로 Redis String에 저장하는 것입니다.