redis切换数据库?thinkphp redis 怎么选择数据库
这篇文章给大家聊聊关于redis切换数据库,以及thinkphp redis 怎么选择数据库对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
如果redis中放入多个数据库表,怎么区分
1、redis
中的每一个数据库,都由一个
redisDb
的结构存储。其中,redisDb.id
存储着
redis
数据库以整数表示的号码。redisDb.dict
存储着该库所有的键值对数据。redisDb.expires
保存着每一个键的过期时间。
2、当redis
服务器初始化时,会预先分配
16
个数据库(该数量可以通过
配置文件
配置),所有数据库保存到结构
redisServer
的一个成员
redisServer.db
数组中。当我们选择数据库
select
number
时,程序直接通过
redisServer.db[number]
来切换数据库。有时候当程序需要知道自己是在哪个数据库时,直接读取
redisDb.id
即可。
redis有哪些集群模式
Redis集群一般有5种:
1,主从复制
2,哨兵模式
3,Redis官方提供的Cluster集群模式(服务端)
4,Jedis sharding集群(客户端sharding)
5,利用中间件代理,比如豌豆荚的codis等
介绍完他们的模式,现在来分析一下他们的原理:
主从复制(Master-Slave Replication):
实现主从复制(Master-Slave Replication)的工作原理:Slave从节点服务启动并连接到Master之后,它将主动发送一个SYNC命令。Master服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。
如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。
主从复制配置
修改从节点的配置文件:slaveof masterip masterport
如果设置了密码,就要设置:masterauth master-password
哨兵模式:
该模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来,无论是主从模式,还是哨兵模式,这两个模式都有一个问题,不能水平扩容,并且这两个模式的高可用特性都会受到Master主节点内存的限制。
Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用。
Sentinel(哨兵)进程的作用
监控(Monitoring):哨兵(sentinel)会不断地检查你的Master和Slave是否运作正常。
提醒(Notification):当被监控的某个Redis节点出现问题时,哨兵(sentinel)可以通过 API向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel)会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master,并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
Sentinel(哨兵)进程的工作方式
每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING命令。
如果一个实例(instance)距离最后一次有效回复 PING命令的时间超过 down-after-milliseconds选项所指定的值,则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态
当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN),则Master主服务器会被标记为客观下线(ODOWN)
在一般情况下,每个 Sentinel(哨兵)进程会以每 10秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO命令。
当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO命令的频率会从 10秒一次改为每秒一次。
若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING命令返回有效回复,Master主服务器的主观下线状态就会被移除。
Redis官方 Cluster集群模式
Redis Cluster是一种服务器Sharding技术,3.0版本开始正式提供。
在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
Redis集群数据分片
在redis的每一个节点上,都有这么两个东西,一个是插槽(slot)可以理解为是一个可以存储两个数值的一个变量这个变量的取值范围是:0-16383。还有一个就是cluster我个人把这个cluster理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384求余数,这样每个 key都会对应一个编号在 0-16383之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
Jedis sharding集群
Redis Sharding可以说是在Redis cluster出来之前业界普遍的采用方式,其主要思想是采用hash算法将存储数据的key进行hash散列,这样特定的key会被定为到特定的节点上。
庆幸的是,Java Redis客户端驱动Jedis已支持Redis Sharding功能,即ShardedJedis以及结合缓存池的ShardedJedisPool
Jedis的Redis Sharding实现具有如下特点:
采用一致性哈希算法,将key和节点name同时hashing,然后进行映射匹配,采用的算法是MURMUR_HASH。采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的rehashing。一致性哈希只影响相邻节点key分配,影响量小。
为了避免一致性哈希只影响相邻节点造成节点分配压力,ShardedJedis会对每个Redis节点根据名字(没有,Jedis会赋予缺省名字)会虚拟化出160个虚拟节点进行散列。根据权重weight,也可虚拟化出160倍数的虚拟节点。用虚拟节点做映射匹配,可以在增加或减少Redis节点时,key在各Redis节点移动再分配更均匀,而不是只有相邻节点受影响。
ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,这样通过合理命名key,可以将一组相关联的key放入同一个Redis节点,这在避免跨节点访问相关数据时很重要。
利用中间件代理
中间件的作用是将我们需要存入redis中的数据的key通过一套算法计算得出一个值。然后根据这个值找到对应的redis节点,将这些数据存在这个redis的节点中。
常用的中间件有这几种
Twemproxy
Codis
nginx
thinkphp redis 怎么选择数据库
1、redis中的每一个数据库,都由一个 redisDb的结构存储。其中,redisDb.id存储着 redis数据库以整数表示的号码。redisDb.dict存储着该库所有的键值对数据。redisDb.expires保存着每一个键的过期时间。
2、当redis服务器初始化时,会预先分配 16个数据库(该数量可以通过配置文件配置),所有数据库保存到结构 redisServer的一个成员 redisServer.db数组中。当我们选择数据库 select number时,程序直接通过 redisServer.db[number]来切换数据库。有时候当程序需要知道自己是在哪个数据库时,直接读取 redisDb.id即可。
3、既然我们知道一个数据库的所有键值都存储在redisDb.dict中,那么我们要知道如果找到key的位置,就有必要了解一下dict的结构了:
typedef struct dict{
//特定于类型的处理函数
dictType*type;
//类型处理函数的私有数据
void*privdata;
//哈希表(2个)
dictht ht[2];
//记录 rehash进度的标志,值为-1表示 rehash未进行
int rehashidx;
//当前正在运作的安全迭代器数量
int iterators;
} dict;
由上述的结构可以看出,redis的字典使用哈希表作为其底层实现。dict类型使用的两个指向哈希表的指针,其中 0号哈希表(ht[0])主要用于存储数据库的所有键值,而1号哈希表主要用于程序对 0号哈希表进行 rehash时使用,rehash一般是在添加新值时会触发,这里不做过多的赘述。所以redis中查找一个key,其实就是对进行该dict结构中的 ht[0]进行查找操作。
4、既然是哈希,那么我们知道就会有哈希碰撞,那么当多个键哈希之后为同一个值怎么办呢?redis采取链表的方式来存储多个哈希碰撞的键。也就是说,当根据key的哈希值找到该列表后,如果列表的长度大于1,那么我们需要遍历该链表来找到我们所查找的key。当然,一般情况下链表长度都为是1,所以时间复杂度可看作o(1)。
二、当redis拿到一个key时,如果找到该key的位置。
了解了上述知识之后,我们就可以来分析redis如果在内存找到一个key了。
1、当拿到一个key后, redis先判断当前库的0号哈希表是否为空,即:if(dict->ht[0].size== 0)。如果为true直接返回NULL。
2、判断该0号哈希表是否需要rehash,因为如果在进行rehash,那么两个表中者有可能存储该key。如果正在进行rehash,将调用一次_dictRehashStep方法,_dictRehashStep用于对数据库字典、以及哈希键的字典进行被动 rehash,这里不作赘述。
3、计算哈希表,根据当前字典与key进行哈希值的计算。
4、根据哈希值与当前字典计算哈希表的索引值。
5、根据索引值在哈希表中取出链表,遍历该链表找到key的位置。一般情况,该链表长度为1。
6、当 ht[0]查找完了之后,再进行了次rehash判断,如果未在rehashing,则直接结束,否则对ht[1]重复345步骤。
到此我们就找到了key在内存中的位置了。
好了,关于redis切换数据库和thinkphp redis 怎么选择数据库的问题到这里结束啦,希望可以解决您的问题哈!