[REDIS] 캐싱 애플리케이션에서 디스크 대 레디 스의 성능
REDIS캐싱 애플리케이션에서 디스크 대 레디 스의 성능
파이썬에서 레디 스 캐시를 만들고 싶었, 어떤 자기 존중 과학자로 나는 성능을 테스트하는 벤치 마크를 만들었다.
흥미롭게도, 레디 스 너무 잘 지내지 않았다. 어느 파이썬 뭔가 마법 (파일 저장) 또는 레디 스의 내 버전을하는 일은 엄청나게 느리다.
이 때문에 내 코드의 구조 방법, 또는 무엇 인 경우는 모르겠지만, 나는 레디 스 그것보다 더 잘 할 것으로 예상했다.
레디 스 캐시하려면 나는 5 분의 만료와 파일 이름에서 파생 된 키 (이 경우, HTML 페이지에) 내 바이너리 데이터를 설정합니다.
모든 경우에, 파일 처리 (이 빨리 f.readlines () 이상 ~ 3 배를하고, 나는 이진 BLOB 필요) () f.read로 이루어집니다.
내 비교에서 누락이 무엇인가, 아니면 레디 스 정말 아무 디스크에 대한 일치하지 않습니다? 파이썬은 파일 곳을 캐싱하고, 매번 reaccessing 있습니까? 왜 이런 일이 레디 스에 대한 접근보다 훨씬 빠르다?
내가 레디 스 2.8, 파이썬 2.7을 사용하고-평을 레디 스있어, 64의 모든 우분투 시스템을 비트.
내가 파이썬 객체의 파일 데이터를 저장하는 기능을 만들어 영원히 열매를 산출 나는 파이썬 특히 마법의 아무것도 생각하지 않습니다.
나는 그룹화하는 것이 네 개의 함수 호출이 :
파일 X 시간을 읽기
레디 스 객체가 메모리에 남아 있는지 확인하기 위해 호출되는 함수는로드, 또는 캐시 새 파일 (단일 및 다중 레디 스 인스턴스).
(레디 스의 단일 및 다중 인스턴스)가 레디 스 데이터베이스로부터의 결과를 얻을 수 생성기를 생성하는 함수.
그리고 마지막으로, 메모리에 파일을 저장하고 영원히 열매를 산출.
import redis
import time
def load_file(fp, fpKey, r, expiry):
with open(fp, "rb") as f:
data = f.read()
p = r.pipeline()
p.set(fpKey, data)
p.expire(fpKey, expiry)
p.execute()
return data
def cache_or_get_gen(fp, expiry=300, r=redis.Redis(db=5)):
fpKey = "cached:"+fp
while True:
yield load_file(fp, fpKey, r, expiry)
t = time.time()
while time.time() - t - expiry < 0:
yield r.get(fpKey)
def cache_or_get(fp, expiry=300, r=redis.Redis(db=5)):
fpKey = "cached:"+fp
if r.exists(fpKey):
return r.get(fpKey)
else:
with open(fp, "rb") as f:
data = f.read()
p = r.pipeline()
p.set(fpKey, data)
p.expire(fpKey, expiry)
p.execute()
return data
def mem_cache(fp):
with open(fp, "rb") as f:
data = f.readlines()
while True:
yield data
def stressTest(fp, trials = 10000):
# Read the file x number of times
a = time.time()
for x in range(trials):
with open(fp, "rb") as f:
data = f.read()
b = time.time()
readAvg = trials/(b-a)
# Generator version
# Read the file, cache it, read it with a new instance each time
a = time.time()
gen = cache_or_get_gen(fp)
for x in range(trials):
data = next(gen)
b = time.time()
cachedAvgGen = trials/(b-a)
# Read file, cache it, pass in redis instance each time
a = time.time()
r = redis.Redis(db=6)
gen = cache_or_get_gen(fp, r=r)
for x in range(trials):
data = next(gen)
b = time.time()
inCachedAvgGen = trials/(b-a)
# Non generator version
# Read the file, cache it, read it with a new instance each time
a = time.time()
for x in range(trials):
data = cache_or_get(fp)
b = time.time()
cachedAvg = trials/(b-a)
# Read file, cache it, pass in redis instance each time
a = time.time()
r = redis.Redis(db=6)
for x in range(trials):
data = cache_or_get(fp, r=r)
b = time.time()
inCachedAvg = trials/(b-a)
# Read file, cache it in python object
a = time.time()
for x in range(trials):
data = mem_cache(fp)
b = time.time()
memCachedAvg = trials/(b-a)
print "\n%s file reads: %.2f reads/second\n" %(trials, readAvg)
print "Yielding from generators for data:"
print "multi redis instance: %.2f reads/second (%.2f percent)" %(cachedAvgGen, (100*(cachedAvgGen-readAvg)/(readAvg)))
print "single redis instance: %.2f reads/second (%.2f percent)" %(inCachedAvgGen, (100*(inCachedAvgGen-readAvg)/(readAvg)))
print "Function calls to get data:"
print "multi redis instance: %.2f reads/second (%.2f percent)" %(cachedAvg, (100*(cachedAvg-readAvg)/(readAvg)))
print "single redis instance: %.2f reads/second (%.2f percent)" %(inCachedAvg, (100*(inCachedAvg-readAvg)/(readAvg)))
print "python cached object: %.2f reads/second (%.2f percent)" %(memCachedAvg, (100*(memCachedAvg-readAvg)/(readAvg)))
if __name__ == "__main__":
fileToRead = "templates/index.html"
stressTest(fileToRead)
그리고 지금 결과 :
10000 file reads: 30971.94 reads/second
Yielding from generators for data:
multi redis instance: 8489.28 reads/second (-72.59 percent)
single redis instance: 8801.73 reads/second (-71.58 percent)
Function calls to get data:
multi redis instance: 5396.81 reads/second (-82.58 percent)
single redis instance: 5419.19 reads/second (-82.50 percent)
python cached object: 1522765.03 reads/second (4816.60 percent)
결과 파이썬 읽은 엄청나게 빠른 개체) 느린 디스크로부터 판독보다 레디 스, 및 c) 빠른 기능마다 호출보다 B임을 a) 발전기 흥미.
왜 디스크에서 읽기는 레디 스에서 메모리 파일 읽기보다 훨씬 빠른 것?
편집하다: 일부 자세한 내용과 테스트합니다.
내가 할 수있는 기능을 대체
data = r.get(fpKey)
if data:
return r.get(fpKey)
결과에서 많은 차이가 없습니다
if r.exists(fpKey):
data = r.get(fpKey)
Function calls to get data using r.exists as test
multi redis instance: 5320.51 reads/second (-82.34 percent)
single redis instance: 5308.33 reads/second (-82.38 percent)
python cached object: 1494123.68 reads/second (5348.17 percent)
Function calls to get data using if data as test
multi redis instance: 8540.91 reads/second (-71.25 percent)
single redis instance: 7888.24 reads/second (-73.45 percent)
python cached object: 1520226.17 reads/second (5132.01 percent)
각 함수 호출에 새로운 레디 스 인스턴스를 만들기 실제로 읽기 속도에 눈에 띄는 효과가없는, 시험에 대한 시험의 변화는 이득보다 크다.
Sripathi Krishnan 임의의 파일 읽기 구현 제안했다. 정말 도움말을 시작 캐싱 여기서 우리는 이러한 결과에서 볼 수 있듯이이있다.
Total number of files: 700
10000 file reads: 274.28 reads/second
Yielding from generators for data:
multi redis instance: 15393.30 reads/second (5512.32 percent)
single redis instance: 13228.62 reads/second (4723.09 percent)
Function calls to get data:
multi redis instance: 11213.54 reads/second (3988.40 percent)
single redis instance: 14420.15 reads/second (5157.52 percent)
python cached object: 607649.98 reads/second (221446.26 percent)
파일에 변화의 거대한 양의가 퍼센트 차이는 속도 향상의 좋은 지표되지 않도록 읽기입니다.
Total number of files: 700
40000 file reads: 1168.23 reads/second
Yielding from generators for data:
multi redis instance: 14900.80 reads/second (1175.50 percent)
single redis instance: 14318.28 reads/second (1125.64 percent)
Function calls to get data:
multi redis instance: 13563.36 reads/second (1061.02 percent)
single redis instance: 13486.05 reads/second (1054.40 percent)
python cached object: 587785.35 reads/second (50214.25 percent)
내가 사용 random.choice (파일 목록) 무작위로 기능을 통해 각 패스에 새 파일을 선택합니다.
전체 요점은 누군가가 그것을 밖으로 시도하려는 경우 여기에있다 - https://gist.github.com/3885957
편집 편집 : (함수 호출 및 발전기의 성능이 매우 유사하지만) 나는 발전기에 대한 하나 개의 파일을 호출하는 것을 몰랐어요. 여기뿐만 아니라 발전기에서 다른 파일의 결과입니다.
Total number of files: 700
10000 file reads: 284.48 reads/second
Yielding from generators for data:
single redis instance: 11627.56 reads/second (3987.36 percent)
Function calls to get data:
single redis instance: 14615.83 reads/second (5037.81 percent)
python cached object: 580285.56 reads/second (203884.21 percent)
해결법
-
==============================
1.이 오렌지 비교에 사과입니다. http://redis.io/topics/benchmarks 참조
이 오렌지 비교에 사과입니다. http://redis.io/topics/benchmarks 참조
레디 스 효율적인 원격 데이터 저장소이다. 명령이 레디 스에서 실행 때마다 메시지가 레디 스 서버로 전송하고, 클라이언트가 동기 인 경우, 그 블록은 응답을 기다리는. 명령 자체의 비용을 넘어 그래서, 당신은 네트워크 왕복 또는 IPC에 대해 지불 할 것입니다.
현대 하드웨어, 네트워크 왕복 또는 IPC를 다른 작업에 비해 놀라 울 정도로 비싸다. 이것은 여러 가지 요인 때문이다 :
이제, 결과를 검토 할 수 있습니다.
발전기 및 함수 호출을 사용하여 하나를 사용하여 구현을 비교, 그들은 레디 스에 왕복 동일한 번호를 생성하지 않습니다. 발전기를 사용하면 간단하게 가지고 :
while time.time() - t - expiry < 0: yield r.get(fpKey)
반복 당 1 왕복 그래서. 기능과 함께, 당신은 :
if r.exists(fpKey): return r.get(fpKey)
반복 당 2 왕복 그래서. 당연히 발전기는 빠른 없다.
물론 당신은 최적의 성능을 위해 같은 레디 스 연결을 다시 사용하기로되어있다. 체계적 / 단절을 연결하는 벤치 마크를 실행하는 데 아무 문제가 없었다.
마지막으로, 레디 스 사이의 성능 차이에 대한 것은 호출하고 파일은 단순히 원격 하나에 시내 전화를 비교하고, 읽습니다. 파일은 OS 파일 시스템에 의해 캐시 읽기, 그래서 그들은 커널과 파이썬 사이의 빠른 메모리 전송 작업이다. I / O가 여기에 포함 된 디스크가 없습니다. 레디 스, 당신은 그래서 훨씬 느립니다의 왕복의 비용을 지불해야한다.
from https://stackoverflow.com/questions/12868222/performance-of-redis-vs-disk-in-caching-application by cc-by-sa and MIT license
'REDIS' 카테고리의 다른 글
[REDIS] Memcache의 비교가, 레디 스 분산 캐싱 프레임 워크으로 Ehcache [폐쇄] (0) | 2020.01.12 |
---|---|
[REDIS] AWS 마이크로 인스턴스 레디 스를 설치 (0) | 2020.01.12 |
[REDIS] 레디 스는 반복없이 터지는없이 목록의 모든 값을 가져 오기 (0) | 2020.01.12 |
[REDIS] 레디 스-평 : StrictRedis ()와 레디 스 ()의 차이점은 무엇입니까? (0) | 2020.01.12 |
[REDIS] Node.js를에서 채팅 서버에 대한 레디 스 펍 / 하위 (0) | 2020.01.12 |