05-Redis

2023-11-13

1、Redis为什么快?

1、纯内存操作

2、单线程可以省去多线程时CPU上下文会切换的时间

3、渐进式ReHash、缓存时间戳

        数组需要扩容的时候,他会维护两张hash表,比如第一张的数组长度为6,另一张的数组长度为12,在set和get的时候他只会把这一个节点的数据hash到长度为12的表中。

        Redis用到时间的时候不会使用Thread.currentTimeMiles()方法,这个会方法会调用操作系统,比较耗时,Redis会把时间缓存到内存中。

2、Redis合适的应用场景?

1、分布式缓存

2、分布式锁

3、计数器

4、排行榜(使用有序集合ZSet)

3、Redis6.0之前为什么一直不使用多线程?

1、使用Redis、CPU 不是瓶颈,受制 内存、网络

2、提高Redis, Pipeline(命令批量) 每秒100万个请求

3、单线程,内部维护比较低

4、如果是多线程(线程切换、加锁\解锁、导致死锁问题)

5、惰性Rehash(渐进性式的Rehash)

所以,一般的公司,单线程Redis 就够了。

4、Redis6.0为什么要引入多线程?

1、Redis服务器可以处理8万到10万 QPS,对于80%的公司来说,单线程的Redis已经足够使用。

2、提高Redis, Pipeline(命令批量) 每秒100万个请求

3、但随着越来越复杂的业务场景,有些公司动不动就上亿的交易量,因此需要更大的QPS。

4、常见的解决方案是在分布式架构中对数据进行分区并采用多个服务器,有非常大的缺陷:

        管理的Redis服务器太多,维护代价大

        某些适用于单个Redis服务器的命令不适用于数据分区

        数据分区无法解决热点读/写问题

5、指的是IO的多线程(内部执行命令还是单线程)       

        多线程任务 分摊到 Redis     同步IO中读写 负载。

        相当于多核服务器,一个核来处理IO操作。

5、Redis有哪些高级功能?

Redis的慢查询

        许多存储系统(例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设调值,就将这条命令的相关信息(例如:发生时间,耗时,命令的详细信息)记录下来,Redis也提供了类似的功能。

Pipeline    批量处理

事务、

数据持久化(RDB和AOF)、

使用哨兵实现集群、

分布式锁

6、为什么要用Redis?

为了高性能、高并发。

7、Redis与memcached相对有哪些优势?

Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。

8、怎么理解Redis中事务?

事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

Redis提供了简单的事务功能,将一组需要一起执行的命令放到multi和exec两个命令之间。

multi 命令代表事务开始,exec命令代表事务结束。另外discard命令是回滚。

注意:

        1、Redis的事务功能很弱。在事务回滚机制上,Redis只能对基本的语法错误进行判断。

        2、运行时错误
        例如:事务内第一个命令简单的设置一个string类型,第二个对这个key进行sadd命令,这种就是运行时命令错误,因为语法是正确的:

可以看到Redis并不支持回滚功能,第一个set命令已经执行成功,需要自己手动修复这类问题。

9、Redis的过期策略

redis采用的是 定期删除+惰性删除 策略。

1、为什么不用定时删除策略?

   定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU

资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.

2、定期删除 + 惰性删除是如何工作的呢?

定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis

不是每个100ms将所有的key检查一次,而是随机抽取进行检查,如果这块区域超过25%过期,会

对这块区域再次进行删除。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。 于

是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置

了过期时间那么是否过期了?如果过期了此时就会删除。

10、什么是缓存穿透?如何避免?

缓存穿透:指查询一个不存在的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。

解决方案:

1.查询返回的数据为空,仍把这个空结果null进行缓存,但过期时间会比较短;

2.布隆过滤器:将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对 DB 的查询。

11、什么是缓存雪崩?如何避免?

缓存雪崩:设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到

DB,DB 瞬时压力过重雪崩。与缓存击穿的区别:雪崩是很多 key,击穿是某一个key 缓存。

12、使用Redis如何设计分布式锁?

基于 Redis 实现的分布式锁,使用到的是 SETNX 命令,有可能会出现死锁现象,锁过期时间不好评估,如果key的过期时间太短,拿到锁的线程还没有执行完业务流程,其他的线程就再次拿到锁了,如果key的过期时间太长,拿到锁的线程如果发生了异常,其他的线程就必须要等锁过期了才能拿到锁,这时候就需要我们开启一 个「守护线程」,定时去检测这个锁的失效时间,如果锁快要过期了,操作共享资源还末完成,那么就自动对锁进行 「续期」,重新设置过期时间。这个守护线程我们一般也把它叫做「看门狗」线程。

13、什么是bigkey?会有什么影响?

1、bigkey是指key对应的value所占的内存空间比较大。

如果按照数据结构来细分的话,一般分为字符串类型bigkey和非字符串类型bigkey。

字符串类型:体现在单个value值很大,一般认为超过10KB就是bigkey

非字符串类型:哈希、列表、集合、有序集合,体现在元素个数过多。

2、bigkey的危害体现在三个方面:

        内存空间不均匀

        操作bigkey比较耗时

        网络拥塞:每次获取bigkey产生的网络流量较大

3、如何发现bigkey

        可以通过redis-cli--bigkeys命令统计bigkey的分布。

14、Redis如何解决key冲突?

1、业务隔离。

2、通过添加前缀的方式对key进行设计。

3、“Redis 并发竞争” 问题就是高并发写同一个key时导致的值错误。

常用的解决方法:

  • 乐观锁,watch 命令可以方便的实现乐观锁。注意不要在分片集群中使用。
  • 分布式锁,适合分布式系统环境,分布式锁的实现方式很多,比如 ZooKeeper、Redis 等
  • 时间戳,适合有序场景
  • 消息队列,在并发量很大的情况下,可以通过消息队列进行串行化处理

15、怎么提高缓存命中率?

1、缓存预加载(预热)

2、增加缓存的存储空间,提高缓存的数据、提高命中率

3、调整缓存的存储类型

4、提升缓存的更新频次

16、Redis持久化方式有哪些?有什么区别?

我们一般采用RDB、AOF、混合持久化。

RDB的优缺点:

优点:RDB持久化文件,速度比较快,而且存储的是一个二进制文件,传输起来很方便。

缺点:RDB无法保证数据的绝对安全,有时候就是1s也会有很大的数据丢失。

AOF的优缺点:

优点:AOF相对RDB更加安全,一般不会有数据的丢失或者很少,官方推荐同时开启AOF和RDB。

缺点:AOF持久化的速度,相对于RDB较慢,存储的是一个文本文件,到了后期文件会比较大,传输困难。

17、为什么Redis需要把所有数据放到内存中?

Redis为了达到最快的读写速度,将数据都读到内存中,并通过异步的方式将数据写入磁盘,所以Redis

具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响Redis的性能。

18、如何保证缓存与数据库双写时的数据一致性

第一种方案:采用延时双删策略

具体的步骤就是:

        先删除缓存;

        再写数据库;

        休眠500毫秒;

        再次删除缓存。

第二种方案:异步更新缓存(基于订阅binlog的同步机制)

技术整体思路:

        MySQL binlog增量订阅消费+消息队列+增量数据更新到redis

19、Redis集群方案应该怎么做?

1. Redis Sentinel(哨兵),体量较小时,选择 Redis Sentinel,单主 Redis 足以支撑业务。

哨兵模式基于主从复制模式。

哨兵顾名思义,就是来为Redis集群站哨的,一旦发现问题能做出相应的应对处理。其功能包括

  1. 监控master、slave是否正常运行
  2. 当master出现故障时,能自动将一个slave转换为master(大哥挂了,选一个小弟上位)
  3. 多个哨兵可以监控同一个Redis,哨兵之间也会自动监控

2、Redis Cluster   Redis 官方提供的集群化方案,体量较大时,选择 Redis Cluster,通过分片,使用更多内存。

哨兵模式解决了主从复制不能自动故障转移,达不到高可用的问题,但还是存在难以在线扩容,

Redis容量受限于单机配置的问题。Cluster模式实现了Redis的分布式存储,即每台节点存储不同

的内容(将16383个槽进行平分),来解决在线扩容的问题。

Cluster模式集群节点最小配置6个节点(3主3从,因为需要半数以上),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。

所有的redis节点彼此互联(PING-PONG机制)。

3、Twemprox (了解)

        Twemprox是Twtter开源的一个 Redis和 Memcached 代理服务器,主要用于管理 Redis和Memcached 集群,减少与Cache 服务器直接连接的数量。

4. Codis (了解)

        Codis是一个代理中间件,当客户端向Codis发送指令时,Codis负责将指令转发到后面的Redis来执行,并将结果返回给客户端。一个Codis实例可以连接多个Redis实例,也可以启动多个Codis实例来支撑,每个Codis节点都是对等的,这样可以增加整体的QPS需求,还能起到容灾功能。

20、Redis集群方案什么情况下会导致整个集群不可用?

1、当访问一个 Master 和 他的Slave 节点都挂了的时候,会报 槽无法获取。如果我们配置了一个

参数,即使有槽没有分配也是可以使用的。

2、当集群 Master 节点个数小于 3 个的时候,或者集群可用节点个数为偶数的时候,基于 fail 的

种选举机制 的自动主从切换过程 可能会不能正常工作。

21、说一说Redis哈希槽的概念?

slot:称为哈希槽

        Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

使用哈希槽的好处就在于可以方便的添加或移除节点。

        当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;

        当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;

22、Redis集群会有写操作丢失吗?为什么?

1、过期 key 被清理

2、最大内存不足,导致 Redis 自动清理部分 key 以节省空间

3、主库故障后自动重启,从库 异步进行同步

4、单独的主备方案,网络不稳定触发 哨兵的自动切换主从节点,切换期间会有数据丢失。

23、Redis常见性能问题和解决方案有哪些?

1、持久化性能问题

        主从 主节点(master)不要做持久化,从节点(slave)做持久化

2、如果数据比较重要,从节点(slave)开启AOF, 策略每秒同步一次

3、在同一个局域网内,主从复制会流畅。

4、 尽量避免 主库 压力很大的情况下,增加从库

5、主从复制 不要采用网状结构、要采用线性结构

24、热点数据和冷数据是什么

1、热数据

        比如点赞数、评论数这些不断变化的数据,考虑使用缓存, 同步到redis.

2、冷数据

        经常不访问的数据

3、如何判断是冷数据还是热数据

        数据更新之前至少读取2次----才能放缓存

25、什么情况下可能会导致Redis阻塞?

1、客户端使用了可能造成阻塞的命令

        keys *  、Hgetall  、smembers  等,

2、Bigkey删除, 比如zset (删除100万的元素 需要2S)

3、清空库的时候,比如 flushdb    flushall

4、AOF日志同步写,记录AOF日志大量的写操作,1个同步写磁盘耗时需要1 ~2ms。

5、 从库加载RDB文件的时候

26、Redis的内存淘汰机制?LRU算法是什么?

以下三个都是设置了过期时间的:

        volatile-lru: 尝试回收最少使用的键(LRU)

        volatile-ttl: 优先回收存活时间(TTL)较短的键,

        volatile-random: 回收随机的键

以下两个是针对所有的键:

        allkeys-lru: 尝试回收最少使用的键(LRU)

        allkeys-random: 回收随机的键

LRU算法

        类似于mybatis的管理page的链表,也是用到了LRU算法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

05-Redis 的相关文章

  • Stackexchange.redis 缺乏“WAIT”支持

    我在客户端应用程序正在使用的负载均衡器后面有 3 个 Web API 服务器 我正在使用这个库来访问具有一个主服务器和几个从服务器的 Redis 集群 目前不支持 WAIT 操作 我需要此功能来存储新创建的用户会话并等待它复制到所有从属服务
  • 仅当尚未设置时才进行原子设置

    仅当尚未在 Redis 中设置时 是否有办法执行原子设置 具体来说 我正在创建一个像 myapp user user email 这样的用户 并且希望 Redis 在 user email 已被占用时返回错误 而不是默默地替换旧值 比如声明
  • 如何让客户端下载动态生成的非常大的文件

    我有一个导出功能 可以读取整个数据库并创建一个包含所有记录的 xls 文件 然后文件被发送到客户端 当然 导出完整数据库的时间需要大量时间 并且请求很快就会以超时错误结束 处理这种情况的最佳解决方案是什么 例如 我听说过使用 Redis 创
  • 如何在节点redis客户端上设置读取超时?

    在 github 上我没有看到读取超时的选项 https github com NodeRedis node redis https github com NodeRedis node redis There s connect timeo
  • Docker-compose Predis 不通过 PHP 连接

    我正在尝试使用 docker compose 将 PHP 与 redis 连接 docker compose yml version 2 services redis image redis 3 2 2 php image company
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • 如何将 ActionController::Live 与 Resque + Redis 一起使用(用于聊天应用程序)

    我正在尝试为我的 Rails 应用程序构建聊天功能 我在用ActionController Live Puma Resque Redis为了这 所以基本上在这种情况下 redissubscribe方法正在后台运行 使用resque 到目前为
  • Caffeine Expiry 中如何设置多个过期标准?

    我正在使用 Caffeine v2 8 5 我想创建一个具有可变到期时间的缓存 基于 值的创建 更新以及 该值的最后一次访问 读取 无论先发生什么都应该触发该条目的删除 缓存将成为三层值解析的一部分 The key is present i
  • 如何将node.js管道传输到redis?

    我有很多数据要插入 SET INCR 到redis DB 所以我正在寻找pipeline http redis io topics pipelining 质量插入 http redis io topics mass insert通过node
  • SignalR 无法连接到 SSL 上的 Azure Redis

    我目前在 Azure 上托管我的 redis 缓存服务器 并让 signalR 依赖它作为骨干 使用以下内容 GlobalHost DependencyResolver UseRedis 服务器 端口 密码 eventKey 这可以在端口
  • 无法启动redis.service:单元redis-server.service被屏蔽

    我在 ubuntu 16 04 上安装了 Redis 服务器 但是当我尝试使用启动redis服务时 sudo systemctl start redis 我收到消息 Failed to start redis service Unit re
  • 有没有办法在 ruby​​ 中重新定义 []=+

    我正在尝试编写一个简单的 DSL 针对 Redis 并且我想自己定义 I have def key val redis zadd name val key end 我想定义 def key val redis zincrby name va
  • 如何在Redis中进行持久化存储?

    关闭redis服务器后 使用set存储的值被破坏 在这里我找到了使用持久性存储的方法 有人帮助我 如何使用javascript实现这一点 我想将客户端的一些值存储在 redis 数据库中 并且必须在其他客户端中使用该值 您需要配置 Redi
  • Redis发布/订阅:查看当前订阅了哪些频道

    我目前有兴趣查看我拥有的 Redis 发布 订阅应用程序中订阅了哪些频道 当客户端连接到我们的服务器时 我们将它们注册到如下所示的通道 user user id 这样做的原因是我希望能够看到谁 在线 目前 我在不知道客户端是否在线的情况下盲
  • 2 个具有共享 Redis 依赖的 Helm Chart

    目前 我有 2 个 Helm Charts Chart A 和 Chart B Chart A 和 Chart B 对 Redis 实例具有相同的依赖关系 如Chart yaml file dependencies name redis v
  • 使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询

    我正在开发一个 Web 应用程序 该应用程序将接收用户的请求 并且必须调用许多外部 API 来编写对该请求的答案 这可以直接从主 Web 线程使用 gevent 之类的东西来扇出请求来完成 或者 我在想 我可以将传入的请求放入队列中 并使用
  • 创建 C++ Redis 模块 - “不导出 RedisModule_OnLoad() 符号”

    我在加载 Redis 模块时遇到一些问题 我只是复制来自的示例https redis io topics modules intro https redis io topics modules intro 但我把它剥下来了 include
  • 在 Spring 4 中干掉通用的 RedisTemplate

    我读到你可以拥有 Autowired从 Spring 4 开始泛型 这太棒了 我有一个摘要RedisService我想参加的课程 Autowired一个通用的 RestTemplate 如下所示 public abstract class
  • 如何使用redis发布/订阅

    目前我正在使用node js和redis来构建应用程序 我使用redis的原因是因为发布 订阅功能 该应用程序只是在用户进入用户或离开房间时通知经理 function publishMsg channel mssage redisClien
  • Spring Redis 排序键

    我在 Redis Spring Data Redis 中有以下键 localhost gt Keys 1 id 1 Name C5796 Site DRG1 2 id 2 Name CX1XE Site DG1 3 id 3 Name C5

随机推荐

  • 原生 servlet 接收和发送 json

    文章目录 接收 发送 接收 private String getBodyStr javax servlet http HttpServletRequest request throws IOException BufferedReader
  • Cisco虚拟局域网命令详细(VLAN)

    目录 1 vlan virtual lan 2 分割广播域的方法 3 VLAN的优势 4 交换机接口划分VLAN的方法 5 VLAN的号码范围 6 创建VLAN的方法 7 删除VLAN 8 交换机接口加入VLAN 9 将接口从vlan中移除
  • 怎么创建Anaconda虚拟环境并导入pycharm 最全操作 包括可视化界面和命令行操作 并安装深度学习框架为例

    文章目录 前言 一 Anaconda是什么 二 为什么我们需要虚拟环境 三 使用anaconda来创建我们的虚拟环境 1 打开anaconda 2 进入环境管理 3 创建环境 4 anaconda里安装包 5 配置镜像源 6 命令行管理环境
  • MATLAB 封装发布exe

    从2016a开始到现在的2017 从MATLAB中创建出一个独立的应用程序有多种方法 可以用MATLAB提供的现有函数或者现有App 本文介绍的是利用MATLAB的Application Compiler工具创建一个独立的应用程序 以下这个
  • HQL之分区表

    分区表 分区表实际上就是对应一个HDFS文件系统上的独立的文件夹 该文件夹下是该分区所有的数据文件 Hive中的分区就是分目录 把一个大的数据集根据业务需要分割成小的数据集 在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区 这
  • centos安装mysql遇到的问题

    一 提示mysql community libs compat的GPG不对 错误信息 warning var cache yum x86 64 7 mysql57 community packages mysql community lib
  • acc 蓝牙_蓝牙中的三种音频编码:Apt-X、SBC、AAC,请问分别有什么区别?

    展开全部 SBC一般的音频格式 蓝牙传输在不支持AAC aptx的时候都用SBC传输 音质一般 现在80 都是这种格式 AAC 当蓝62616964757a686964616fe4b893e5b19e31333365653164牙支持AAC
  • NCBI(pubmed)里医学主题词(MeSH)完整词库获取

    NCBI pubmed 里医学主题词 MeSH 完整词库获取 转载提示 原创文章 转载前请联系我 文章目录 NCBI pubmed 里医学主题词 MeSH 完整词库获取 前言 一 MeSH词库是什么 二 获取MeSH词库的方式 1 从官网的
  • caffe代码阅读8: Data_layers的实现细节(各个数据读取层的实现细节) 2016.3.25-28

    一 Data layers hpp文件的作用简介 Data layers hpp在目前caffe的master分支中已经不能存在了 分散到各个文件中去了 而之前是存在于cafferoot include caffe中 现在已经变成了各个类的
  • 火线、零线和地线及开关接线参考

    火线 零线和地线及开关接线参考 1 火线 零线和地线 1 1 What is Live wire Live wire L 火线 相线 火线是电路中输送电的电源线 1 2 What is Neutral wire Neutral wire N
  • 2022陕西省网络搭建及应用技能大赛windows服务器搭建部分答案视频

    2022陕西省网络搭建及应用技能大赛windows服务器搭建部分答案视频资源 CSDN文库 https download csdn net download weixin 41687096 87684084
  • Gateway服务网关入门

    Gateway服务网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目 该项目是基于 Spring 5 0 Spring Boot 2 0 和 Project Reactor 等响应式编程和事件流技术
  • Android之 内存泄漏问题检测和解决

    一 背景 1 1 什么是内存泄漏 内存泄漏指程序在申请内存后 无法释放已申请的内存空间 导致系统无法及时回收内存并且分配给其他进程使用 1 2 内存管理 1 3 垃圾回收 上面可以看出GC回收的主要对象是java堆 也就是new出来的对象
  • Zipkin链路追踪

    Zipkin链路追踪技术分享 什么是Zipkin Zipkin 是 Twitter 的一个开源项目 它基于 Google Dapper 实现 它致力于收集服务的定时数据 以 解决微服务架构中的延迟问题 包括数据的收集 存储 查找和展现 我们
  • Python实现移动平均数

    首先 什么是移动平均数呢 来自百度百科 若依次得到测定值 时 按顺序取一定个数所做的全部算术平均值 例如 等是移动平均值 详细可以点击此处链接 Python中是如何实现呢
  • 电子科技大学计算机系统结构复习笔记(三):流水线技术

    目录 前言 重点一览 流水线定义 基本概念 流水线分类 流水线特点 流水线时空图 流水线性能分析 流水线特点 经典5段流水线RISC处理器 流水线的三种冒险 冒险分类 停顿流水线 结构冒险 数据冒险 控制冒险 流水线处理机的指令系统 流水线
  • kitti数据集解析以及在mmdection3d中的pkl文件参数解析

    kiiti数据集介绍 kitti数据集存在4个相机 其中0和1为灰度相机 2和3为彩色相机 各设备之间的安装示意图如下所示 如图所示 相机坐标系 x轴向右 y轴向下 z轴向前 雷达坐标系 x轴向前 y轴向左 z轴向上 GPS IMU坐标系
  • STM32项目设计:基于stm32f4的智能门锁(附项目视频全套教程、源码资料)

    文章目录 智能门锁 一 项目背景 二 项目功能要求 三 元件准备 四 项目设计 一 原理图设计 二 硬件设计 三 程序设计 五 上机调试 六 知识扫盲 七 项目图片展示 智能门锁 资料链接 智能门锁 rar 2022年1月1日前 单片机设计
  • 机器学习项目入门篇:一个完整的机器学习项目

    本部分 我们会作为被一家地产公司雇佣的数据科学家 完整地学习一个项目 下面是主要步骤 项目概述 获取数据 发现并可视化数据 发现规律 为机器学习算法准备数据 选择模型 进行训练 微调模型 给出解决方案 部署 监控 维护系统 一 项目概述 任
  • 05-Redis

    1 Redis为什么快 1 纯内存操作 2 单线程可以省去多线程时CPU上下文会切换的时间 3 渐进式ReHash 缓存时间戳 数组需要扩容的时候 他会维护两张hash表 比如第一张的数组长度为6 另一张的数组长度为12 在set和get的