缓存Tair高性能使用规范

简介: 2x.png不要短时间大量重复读写相同的keyserver端的原理是网络收包后,放入到工作队列(读写队列分离,但都只有一个),再由工作线程从队列中取出进行处理。
img_04fd0ae44c014a220b35ebd64fdfa5b9.png
2x.png

不要短时间大量重复读写相同的key

server端的原理是网络收包后,放入到工作队列(读写队列分离,但都只有一个),再由工作线程从队列中取出进行处理。这里一个问题是,为保证数据的正确性,会对同一个key的读写加锁,而如果存在大量读写同一个key的情况,则势必会阻塞其他线程(锁不慢,锁竞争才慢),导致拖慢整个服务端的处理速度。

不要使用时间戳作为key的一部分,容易导致一段时间内所有流量都访问一台服务端机器,导致服务端压力过大而出现大量超时


Value大小多大合适

value建议不超过50KB,value越大,服务端能承受qps越低,请求耗时越大,当value大小超过1MB时,缓存失效,读写性能将严重受影响


超时时间设置多少合适

普通kv接口:单key请求超时时间建议设置100ms以上,批量请求超时时间建议设置200ms以上

特殊数据结构接口:超时时间建议设置500ms左右


超时是否需要重试

写超时:除非服务端压力过大丢弃请求,否则所有写请求在服务端都会执行成功,只是没有返回结果给客户端,除非业务逻辑依赖数据的强一致性,否则不需要重试

读超时:如果是批量接口,建议设置返回比例(参数为BatchReturnPercent),如果需要重试,建议sleep 100ms左右后重试,重试不要超过3次


批量请求使用注意

批量请求key个数

批量请求key个数建议不要超过100个

batchGet请求如何提升可用性

可以设置批量请求返回比例(参数为BatchReturnPercent)


复杂数据结构中元素不宜过多

tair目前引擎对于复杂数据结构,如list,set,map,prefix接口,支持的不够友好。

这些复杂数据结构的元素不要存储超过2000个,后续服务端会限制元素个数,个数超过后禁止写入。


作为缓存使用时,不要在获取数据失败时直接重写缓存数据

获取数据失败的原因很多,但是只有在确定数据不存在的情况下,才需要重写缓存数据。如果没有正确区分失败的情况就直接重写缓存数据,则可能会加剧失败的可能,同时会对集群造成更大的压力。例如在超时的情况下重写缓存数据,超时次数可能会更多,且有雪崩的风险。

只有出现下面其中一个返回码时,才需要重写缓存数据:

  • NOTEXIST (-3998) - 数据不存在
  • EXPIRED (-3988) - 数据已过期

Prefix接口相关

不要在同一个pkey下存放过多skey

一个pkey下skey个数建议小于1000,在同一个pkey下存放过多的skey可能会导致性能问题。同一个pkey下的所有skey数据在物理上都存放在同一个机器上,当skey数量过多时,到同一台机器的请求也会增多。如果存在一个pkey是热点key, 则热点流量会集中到一台机器上,且无法通过扩容均衡压力。一种极端的错误使用情况是,整个数据空间只有一个pkey, 所有数据都作为skey,这个情况下整个集群的全部流量都集中在集群中的一台机器上,造成整个集群的性能降低为只相当于单机的性能。为了避免这些情况,不要在pkey下存放过多skey, 并且在整个数据空间中需要存在足够数量的pkey,以将流量均衡到集群中的各台机器上。

batchPrefixGetMulti接口使用注意

该接口没有部分返回机制和重试机制,容易受网络问题、热点问题等影响而出现少量超时,减少每个包中的pkey个数可以缓解

优先使用prefixGet,而不是getRange

prefixGet比getRange拥有更好的性能。prefixGet会优先从内存缓存中获取数据,而getRange只能通过磁盘扫描来获取数据。

注意传入getRange接口的参数

传入getRange接口的参数,对于getRange接口的性能,以及对集群造成的压力都有很重要的影响,因此传入正确的参数非常重要。

  1. 尽量设置skey的范围,即skey_start和skey_end

  2. offset不宜较大,可以通过设置skey_start,而避免设置offset为较大的数值

可能需要多次调用getRange来获取全部数据

getRange接口最多返回1M的数据。如果pkey下面skey的value较大,全部数据大小超过了1M,getRange只会返回1M的数据,同时返回码为HAS_MORE_DATA。

getRange接口有三个较重要的返回码:

  • OK (0) - 表示参数中要求的所有数据都已正确获取
  • HAS_MORE_DATA (150) - 只获取了参数中要求的部分数据,需要再次调用来获取剩余数据。需要注意的是,再次调用时需要调用者调整调用参数。
  • NOTEXIST (-3998) - 参数中要求的数据不存在

因此,当getRange接口返回HAS_MORE_DATA时,则需要调用者根据已经获取到的数据,调整调用参数,继续调用getRange来获取剩余的数据,直到getRange返回OK或者NOT_EXIST。


欢迎关注 高广超的简书博客 与 收藏文章 !
欢迎关注 头条号:互联网技术栈

个人介绍:

高广超:多年一线互联网研发与架构设计经验,擅长设计与落地高可用、高性能、可扩展的互联网架构。

本文首发在 高广超的简书博客 转载请注明!

目录
相关文章
|
2月前
|
缓存 算法 Java
Caffeine Cache~高性能 Java 本地缓存之王
Caffeine Cache~高性能 Java 本地缓存之王
82 1
|
4月前
|
存储 缓存 安全
Go 简单设计和实现可扩展、高性能的泛型本地缓存
本文将会探讨如何极简设计并实现一个可扩展、高性能的本地缓存。支持多样化的缓存策略,例如 最近最少使用(LRU)等。
73 0
Go 简单设计和实现可扩展、高性能的泛型本地缓存
|
存储 缓存 负载均衡
Tair分布式缓存
Redis很好用,相比memcached多了很多数据结构,支持持久化。但是在很长一段时间里,原生是不支持分布式的。后来就出现了很多redis集群类产品,Tair是其中胜出的优秀作品之一。 所以Tair的特性都是一些集群的特性,比如:容错、解决单点故障、跨机房管理、多集群管理、支持副本等。总而言之,是redis的高可用版本。
1246 1
Tair分布式缓存
|
5天前
|
缓存 算法 Java
Java本地高性能缓存实践
本篇博文将首先介绍常见的本地缓存技术,对本地缓存有个大概的了解;其次介绍本地缓存中号称性能最好的Cache,可以探讨看看到底有多好?怎么做到这么好?最后通过几个实战样例,在日常工作中应用高性能的本地缓存。
|
3月前
|
存储 缓存 算法
Golang高性能内存缓存库BigCache设计与分析
【2月更文挑战第4天】分析Golang高性能内存缓存库BigCache设计
82 0
|
9月前
|
缓存 关系型数据库 MySQL
高性能内存对象缓存Memcached
高性能内存对象缓存Memcached案例
|
9月前
|
存储 缓存 安全
百度搜索:蓝易云【Java本地高性能缓存的几种实现方式。】
Java 本地高性能缓存通常用于存储经常使用的数据,以便在后续的请求中快速访问。以下是几种实现方式:
60 0
|
9月前
|
存储 缓存 NoSQL
高性能缓存和存储:深入了解 Redis 的 String 数据类型
在现代的应用程序中,高性能的缓存和数据存储方案对于提升系统性能和响应速度至关重要。Redis,作为一款高性能的内存数据库,提供了丰富的数据类型来满足不同的需求。在本文中,我们将重点介绍 Redis 的 String 数据类型,探讨其特性、用法以及在实际应用中的优势。
79 0
|
10月前
|
存储 缓存 Java
Sync.Pool无锁ringbuffer队列+双向链表构建高性能缓存池
Sync.Pool无锁ringbuffer队列+双向链表构建高性能缓存池
|
10月前
|
存储 消息中间件 缓存
Redis入门指南:深入了解这款高性能缓存数据库
1. 什么是Redis? Redis(Remote Dictionary Server)是一个开源的,基于内存的高性能键值存储系统。它可以作为数据库、缓存和消息中间件使用。Redis的数据存储在内存中,这使得数据的读写速度非常快,因此它被广泛应用于需要高并发、低延迟的场景中。
100 0