http://www.zhihu.com/question/19764056
A
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:杨海坡
链接:http://www.zhihu.com/question/19764056/answer/20241839
来源:知乎
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:杨海坡
链接:http://www.zhihu.com/question/19764056/answer/20241839
来源:知乎
纯内存数据库,如果只是简单的 key-value,内存不是瓶颈。一般情况下,hash 查找可以达到每秒数百万次的数量级。
瓶颈在于网络 IO 上。
根据你测的的 10000/s 来看,客户端和 redis 应该是部署在两台不同的机器,并且是使用同步的方式请求 redis. 每次请求需要通过网络把请求发送到 redis 所在的机器,然后等待 redis 返回数据。时间大部分消耗在网络传输中。
如果把 redis 和客户端放在同一台机器,网络延迟会更小,一般情况下可以打到 60000 次每秒甚至更高,取决于机器性能。
锁不是影响性能的主要因素。线程锁 (mutex_lock) 只有在遇到冲突的情况下性能会下降,而正常情况下,遇到冲突的概率很低。如果只是简单的加锁、释放锁速度是非常快的,每秒钟上千万次没问题。memcache 内部用到了大量的锁,并没有见到性能降低。
线程也不是影响吞吐量的重要因素。如第一点来说,一般情况下,程序处理内存数据的速度远高于网卡接收的速度。使用线程好处是可以同时处理多条连接,在极端情况下,可能会提高响应速度。
使用 epoll 或 libevent 等因为异步非阻塞 IO 编程只能这么做。与之对应的是同步阻塞 IO 编程,使用多进程或多线程实现多条连接的处理,比如 apache。一般情况下,异步非阻塞 IO 模型性能是远高于同步阻塞 IO 模型的,可以参考 nginx 与 apache 性能的对比。
libevent 并不比 redis 自己实现的 ae_event 慢,代码多是应为 ae_event 只实现了 redis 需要的功能,而 libevent 则具有更多的功能,比如更快的定时器、buffer event 模型,甚至自带了 DNS、HTTP 协议的处理。并且 libevent 更通用,而 redis 只专注于 linux 平台。
最后回答题主问题,快在哪?
1、纯内存操作
2、异步非阻塞 IO
瓶颈在于网络 IO 上。
根据你测的的 10000/s 来看,客户端和 redis 应该是部署在两台不同的机器,并且是使用同步的方式请求 redis. 每次请求需要通过网络把请求发送到 redis 所在的机器,然后等待 redis 返回数据。时间大部分消耗在网络传输中。
如果把 redis 和客户端放在同一台机器,网络延迟会更小,一般情况下可以打到 60000 次每秒甚至更高,取决于机器性能。
锁不是影响性能的主要因素。线程锁 (mutex_lock) 只有在遇到冲突的情况下性能会下降,而正常情况下,遇到冲突的概率很低。如果只是简单的加锁、释放锁速度是非常快的,每秒钟上千万次没问题。memcache 内部用到了大量的锁,并没有见到性能降低。
线程也不是影响吞吐量的重要因素。如第一点来说,一般情况下,程序处理内存数据的速度远高于网卡接收的速度。使用线程好处是可以同时处理多条连接,在极端情况下,可能会提高响应速度。
使用 epoll 或 libevent 等因为异步非阻塞 IO 编程只能这么做。与之对应的是同步阻塞 IO 编程,使用多进程或多线程实现多条连接的处理,比如 apache。一般情况下,异步非阻塞 IO 模型性能是远高于同步阻塞 IO 模型的,可以参考 nginx 与 apache 性能的对比。
libevent 并不比 redis 自己实现的 ae_event 慢,代码多是应为 ae_event 只实现了 redis 需要的功能,而 libevent 则具有更多的功能,比如更快的定时器、buffer event 模型,甚至自带了 DNS、HTTP 协议的处理。并且 libevent 更通用,而 redis 只专注于 linux 平台。
最后回答题主问题,快在哪?
1、纯内存操作
2、异步非阻塞 IO
B
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:王威
链接:http://www.zhihu.com/question/19764056/answer/12889462
来源:知乎
C
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:王威
链接:http://www.zhihu.com/question/19764056/answer/12889462
来源:知乎
目前想到的原因有这几方面。
- Libevent。和Memcached不同,Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event loop(4)。业界不少开发者也建议Redis使用另外一个libevent高性能替代libev,但是作者还是坚持Redis应该小巧并去依赖的思路。一个印象深刻的细节是编译Redis之前并不需要执行./configure。
- CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源的方法。CAS实现需要为每个cache key设置一个隐藏的cas token,cas相当value版本号,每次set会token需要递增,因此带来CPU和内存的双重开销,虽然这些开销很小,但是到单机10G+ cache以及QPS上万之后这些开销就会给双方相对带来一些细微性能差别(5)。
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:fullsail
链接:http://www.zhihu.com/question/19764056/answer/40235031
来源:知乎
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:fullsail
链接:http://www.zhihu.com/question/19764056/answer/40235031
来源:知乎
对于redis 这种cache类型的服务(很多人说redis是数据库,我实在不敢认同)。CPU从来都不是瓶颈。
KV结构内存如果采用Hash存储。内存部分的访问速度是千万级别。
瓶颈是网络和内存。网络对外部请求负载而言,内存是对数据容量而言的。其实如果内存足够,完全可以可以负担更多数据,
就现在的频率的CPU,如果请求量是1W的入出(包数量)压力级别。epoll + one loop 的处理需要的CPU大改也就10%。10W级别应该30%的CPU也足够了(其实应该用不到)。剩余的对付查询,绰绰有余。到时Redis这种用字符串当命令字处理的东东,在字符串处理上会有一定的消耗。
至于memcache 为啥要做成多线程……,请去问作者。我个人认为……,完全没有必要。
CPU这玩意,也只能让他闲着了。为啥要闲着,因为现在硬件设备远远跟不上软件发展。真正的cache服务器,内存应该1T(这样可以部署好几个redis了),网卡也应该提升级别。但你看现在的设备。128G的都是稀罕玩意。万M的网卡倒是有了,但其他地方……。所以。。。CPU闲着也就闲着把。没法子。
KV结构内存如果采用Hash存储。内存部分的访问速度是千万级别。
瓶颈是网络和内存。网络对外部请求负载而言,内存是对数据容量而言的。其实如果内存足够,完全可以可以负担更多数据,
就现在的频率的CPU,如果请求量是1W的入出(包数量)压力级别。epoll + one loop 的处理需要的CPU大改也就10%。10W级别应该30%的CPU也足够了(其实应该用不到)。剩余的对付查询,绰绰有余。到时Redis这种用字符串当命令字处理的东东,在字符串处理上会有一定的消耗。
至于memcache 为啥要做成多线程……,请去问作者。我个人认为……,完全没有必要。
CPU这玩意,也只能让他闲着了。为啥要闲着,因为现在硬件设备远远跟不上软件发展。真正的cache服务器,内存应该1T(这样可以部署好几个redis了),网卡也应该提升级别。但你看现在的设备。128G的都是稀罕玩意。万M的网卡倒是有了,但其他地方……。所以。。。CPU闲着也就闲着把。没法子。
D
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:彭伟
链接:http://www.zhihu.com/question/19764056/answer/13364800
来源:知乎
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:彭伟
链接:http://www.zhihu.com/question/19764056/answer/13364800
来源:知乎
总体来说快速的原因如下:
1)绝大部分请求是纯粹的内存操作(非常快速)
2)采用单线程,避免了不必要的上下文切换和竞争条件
3)非阻塞IO
内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间
这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。
1)绝大部分请求是纯粹的内存操作(非常快速)
2)采用单线程,避免了不必要的上下文切换和竞争条件
3)非阻塞IO
内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间
这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。