1. 首页 > 科技 >

linux 连接redis_linux连接redis密码

linux怎样查看redis是否安装成功

通过

linux 连接redis_linux连接redis密码linux 连接redis_linux连接redis密码


ps

-ef

|grepS: f25b35f208dc96605ee4660994d2ac52f39ac870 127.0.0.1:7006

6379

查看是否服务启动。

redis默认使用这slots: (0 slots) sle个端口启动服务

Redis Sentinel的CPU占有率长期接近的问题 二

slots:10923-16383 (5461 slots)

在 《Redis Sentinel的CPU占有率长期接近的问题》 一文中,通过结合Redis Sentinel的源码,发现由于出现了"Too many open files"问题,致使Sentinel的acceptTcpHandler处理函数会被频繁并快速调用,最终导致了CPU长期接近的现象。但对于为什么会出现“Too many open files”这个问题,本文将在上一篇的基础上,继续探讨和分析。

“Too many open files”这个错误其实很常见,想必大家早已对其有一定的了解,这里打算再简单的介绍一下。

很明显,“Too many open files”即说明打开的文件(包括socket)数量过多,已经超出了系统设定给某个进程的文件描述符的个数,超过后即无法继续打开新的文件,并且报这个错误。

首先,我们需要了解有关open files的基本知识。详细的概念大家可以谷歌,网上也有各种各样的解决办法,这里只对open files做简单的介绍和总结。

我们在linux上运行ulimit -a 后,出现:

如图open files的个数为1024,很明显这个值太小了(linux默认即为1024),当进程耗尽1024个文件或socket后,就会出现“Too many open files”错误。现实生产环境中这个值很容易达到,所以一般都会进行相应修改。

最简单的修改方式是ulimit -n 65535,但这样重启系统后又会恢复。生效的方法是修改/etc/security/limits.conf 文件,在加入:

修改完成后,重启系统或者运行sysctl -p使之生效。

soft 和hard,表示对进程所能打开的文件描述符个数限制,其概念为:

他们的区别就是软限制可以在程序的进程中自行改变(突破限制),而硬限制则不行(除非程序进程有root权限)。

上面的规则大家自己尝试一下,以增加印象。

重启后,运行ulimit -a,可以看到open files 的值改变为:

简单介绍完open files,我们再来了解下file-max。这个参数相信有很多人经常与ulimit中的open files混淆,他们的区别我们必须了解。

file-max 从字面意思就可以看出是文件的个数,运行cat /proc/sys/fs/file-max,可以看到:

这表示当前系统所有进程一共可以打开的文件数量为387311。请务必注意”系统所有进程"这几个字。

运行 vim /etc/sysctl.conf ,有时候你会看到类似:fs.file-max = 8192。出现这个则表示用户手动设置了这个值,没有则系统会有其默认值。手动设置的话,只需要在sysctl.conf 中加上上述语句即可。

回到ulimit中的open files,它与file-max的区别就是:opem filese表示当前shell以及由它启动的进程的文件描述符的限制,也就是说ulimit中设置的open files,只是当前shell及其子进程的文件描述符的限定。是否清楚?可以简单的理解为:

好了,对于 file-max与open files的简单介绍到此为止。现在的问题就是,“Too many open files”到底是碰到哪个设置的雷区造成的。

结合上一篇,我们知道sentinel主要在执行accept函数时出现了“Too many open files”错误,熟悉accept这个系统调用的朋友很清楚,accept会接收客户端的请求,成功的话会建立连接,并返回新的socket描述符。所以,我们确定这里的“Too many open files”指的即是socket的数目过多。

我们猜测,是否是有大量的Jedis连接同时存在,耗尽的socket资源,导致新的连接请求无法建立。所以,我们查看一下sentinel的TCP连接,运行:netstat -anp | grep 26379,得到:

由上图可以发现,有非常多处于ESTABLISHED状态的TCP连接,运行 netstat -anp | grep 118:26379 | wc -l查看他们的个数:

可以看到,Sentinel同时维持了4071个TCP连接,而且过了很久之后,仍然是这么多,不会有大幅变化。

这个值很大,看似一切正常。继续运行sudo cat /proc/5515/limits,发现:

看到上图,我们似乎发现了端倪,这里的hard和soft都是4096,与前面的4072比较接近。为什么会这么低?我们继续查看一下ulimit,运行ulimit -a :

可以看到,ulimit中open files 的设置为64000,为什么会不一致?按理说sentinel应该有64000+的open files。

对于这个矛盾,一开始我怎么也想不明白。我推测:应该是在最早启动sentinel启动的时候,系统的设置为4096,sentinel启动之后,又在某个时间又改为64000,而sentinel进程确保持原有设置,从而导致很快达到限制。

我马上查看了进程的启动时间,运行ps -eo pid,lstart,etime | grep 5515:

发现进程启动于2015年12月2日,接着再次运行 ll /etc/security/limits.conf:

发现确实在2016年4月改动过, 然后我咨询了运维人员,他们告知我,确实改动过,但由多少改动到多少,他们也忘了。。。

为了了解Sentinel启动时的状况,紧接着查看了Sentinel的日志,下面是Sentinel启动时打印的画面:

上图说明了进程是2015年12月2日启动的,特别注意最开头的几行,非常关键:

这几句的意思是:

问题很清楚了,redis sentinel可以支持10000个客户端,也就是10032个文件描述符,但由于当前被人为限制到4096 了,所以,自动降低了标准。

因此,我猜测,最早open files的限制为4096时,Sentinel已经启动了,只要进程启动,改多少都没有用。很明显,在生产环境上,4096个连接请求很快就会达到。

接着,我继续查看了Sentinel的配置文件,如下图所示:

上图中, “Generated by CONFIG REWRITE”之前的都是是人工配置,其后为Sentinel自动重写的配置。

熟悉Redis的朋友都知道。Sentinel可能会对其配置文件进行更新重写:

我们很快注意到了maxclients 4064这个配置项,此时我很迷惑。我们知道,在Sentinel中是无法手动运行config set命令的,那这个4096必然不是来自于人工配置,Sentinel为什么要自动重写4064这个值。其实,仔细发现,这里Sentinel限制了最多4064个连接,加上32个预留,刚好为4096。

于是,综上,我猜测,Sentinel在启动的时候发现自己的10032个open files的预期与事实设置的4096不符,所以被迫遵守4096,减去预留的32,最终maxclients 只有4064,并且之后因为某些原因重写了配置,所以输出了这个值。

好吧,我的一贯作风,先猜测,再让源码说话。

我们可以通过异常信息定位异常所处源码,所以我搜索了前面提到的Sentinel在启动时打印的关于maxclients 的日志信息中的文本,如“Yoequested maxclients of ...”。

这个异常出现在adjustOpenFilesLimit函数,通过函数名可以清楚它的作用,然后发现它的调用链只是:

``main()->init()->adjustOpenFilesLimit()```

所以,可以确定,在Sentinel启动并进行初始化的时候,会调用adjustOpenFilesLimit函数对open files个数进行调整。调整策略是什么呢?我们查看源码:

在第1行中,REDIS_MIN_RESERVED_FDS即预留的32,是Sentinel保留的用于额外的的作,如listening sockets, log files 等。同时,这里读取了server.maxclients的值,看来server.maxclients具有初始化值,通过经过定位源码,发现调用链:

即Sentinel在启动时,调用initConfig()初始化配置,执行了server.maxclients = REDIS_MAX_CLIENTS(REDIS_MAX_CLIENTS为10000),所以server.maxclients就有了初始值10000。

回到adjustOpenFilesLimit()函数,adjustOpenFilesLimit最终目的就是得到适合的soft,并存在server.maxclients中,因为该函数比较重要,下面专门作出解释:

1 先得到maxfiles的初始值,即Sentinel的期望10032

2 然后获取进程当前的soft和hard,并存入limit ,即执行getrlimit(RLIMIT_NOFILE,&limit) :

调整过程为:

1 先用oldlimit变量保存进程当前的soft的值(如4096)

2 然后,判断oldlimit

尝试过程为:

1 首先f保存要尝试的soft值,初始值为maxfiles (10032),即从10032开始调整。

2 然后开始一个循环判断,只要f大于oldlimit,就执行一次setrlimit(RLIMIT_NOFILE,&limit) ,然后f减16:

这样,用这种一步一步尝试的方法,最终可用得到了Sentiel能获得的的soft值,减去32再保存在server.maxclients中。

另外,当得到Sentinel能获得的最合适的soft值f后,还要判断f与oldlimit(系统最初的soft限制,假设为4096),原因如下:

也许会直到f==4096才设置成功,但也会出现f<4096的情况,这是因为跨度为16,一不小心就减多了,但的soft值不应该比4096还小。所以,f=oldlimit就是这个意思。

,还有一个判断:

上面的过程我们用简单的表示为:

adjustOpenFilesLimit()的分析到此结束。但有一点一定要明确,adjustOpenFilesLimit()只会在Sentinel初始化的时候执行一次,目的就是将最合适的soft保存到了server.maxclients (第xx行),以后不会再调用。这样,一旦设置了server.maxclients ,只要Sentinel不重启,这个值就不会变化,这也就解释了为什么Sentinel启动之后再改变open files没有效果的原因了。

那什么时候发生了重写呢?即“Generated by CONFIG REWRITE”这句话什么时候会输出?接着上面,我又在源码里搜索了“Generated by CONFIG REWRITE”这句话,发现了常量REDIS_CONFIG_REWRITE_SIGNATURE,通过它继而发现如下调用链:

上面的调用链中,表示有很多地方会调用sentinelFlushConfig()。

什么时候调用sentinelFlushConfig()呢?经过查找,发现有很多条件都可以触发sentinelFlushConfig函数的调用,包括Leader选举、故障转移、使用Sentinel set 设置命令、Sentinel处理信息等等。[root@localhost ~]# kill -9 9524

而sentinelFlushConfig()则会利用rewriteConfig(),针对具体的配置项,分别进行重写,最终将Sentinel所有的状态持久化到了配置文件中。如下所示,在rewriteConfig()中,可以看到非常多的重写类型, 这些重写类型都是与redis的各个配置选项一一对应的:

当然,我们只需要找到其中关于max clients的重写即可,所以在该函数中,我们找到了调用:

可以看到,该函数传入了Sentinel当前的server.maxclients(已经在启动时调整过了,前面分析过),以及默认的REDIS_MAX_CLIENTS即10032。该函数作用就是将当前的server.maxclients的值重写到配置文件中去。什么时候重写呢,即当默认值与当前值不同的时候(也就是force==true的时候),具体可以查看其源码,篇幅限制我们不做详细介绍。

通过前面一大堆的分析,我们可以得出结论:

讲到这里,还有一个问题就是,为什么Sentinel会长期持有4000多个Established状态的TCP连接而不释放。按目前生产环境的规模,正常情况下业务客户端使用的Jedis建立的TCP连接不应该有这么多。

经过查看,发现Sentinel上的很多连接在对应的客户端中并没有存在。如红框所示IP10.X.X.74上:

总计有992个连接:

而实际上在10.X.X.74上,只有5个与Sentinel的连接长期存在:

也就是说,在Sentinel中有大量的连接是无效的,客户端并没有持有,Sentinel一直没有释放。这个问题, 就涉及到了TCP保活的相关知识。

我们首先要了解,作系统通常会自身提供TCP的keepalive机制,如在linux默认配置下,运行sysctl -a |grep keep,会看到如下信息:

上面表示如果连接的空闲时间超过 7200 秒(2 小时),Linux 就发送保持活动的探测包。每隔75秒发一次,总共发9次,如果9次都失败的话,表示连接失效。

TCP提供这种机制帮助我们判断对端是否存活,当TCP检测到对端不可用时,会出错并通知上层进行处理。keepalive机制默认是关闭的,应用程序需要使用SO_KEEPALIVE进行启用。

了解到这个知识之后,我们开始分析。在Redis的源码中,发现有如下调用链:

还记得acceptTcpHandler吗,acceptTcpHandler是TCP连接的处理器,当它为客户端成功创建了TCP连接后,会通过调用create函数为每个连接(fd)创建一个redis 实例,这个redis 与客户端是一一对应的。并且,还会设置一些TCP选项,如下所示。

如果用户在Redis中没有手动配置tcpkeepalive的话,server.tcpkeepalive = REDIS_DEFAULT_TCP_KEEPALIVE,默认为0。

由第x-x行我们可以明确,Redis与客户端的连接默认是关闭保活机制的,因为只有当server.tcpkeepalive不为0(修改配置文件或config set)时,才能调用anetKeepAlive方法设置TCP的keepalive选项。

但是,TCP连接是双向的,Sentinel无法处理失效连接,那Jedis客户端呢?它是否可以主动断掉连接?我们定位到了Jedis建立连接的函数connect(),如下所示:

由第x行可以看到,Jedis启用了TCP的keepalive机制,并且没有设置其他keepalive相关选项。也就是说,Jedis客户端会采用linux默认的TCP keepalive机制,每隔7200秒去探测连接的情况。这样,即使与Sentinel的连接出问题,Jedis客户端也能主动释放掉,虽然时间有点久。

但是,实际上,如前面所示,Sentinel上有很多失效连接持续保持,为什么会有这种现象?

对于上面的问题,能想到的原因就是,在Jedis去主动释放掉TCP连接前,该连接被强制断掉,没有进行完整的四次挥手的过程。而Sentinel却因为没有保活机制,没有感知到这个动作,导致其一直保持这个连接。

能干掉连接的元凶,马上想到了防火墙,于是我又询问了运维,结果,他们告知了我一个噩耗:

目前,生产环境上防火墙的设置是主动断掉超过10分钟没有数据交换的TCP连接。

好吧,绕了一大圈,至此,问题已经很清楚了。

终于,我们得出了结论:

有了前面的分析,其实解决办法很简单:

关于“Redis Sentinel的CPU占有率长期接近的问题”到此就结束了,在写这两篇博文的时候,我收货了很多自己没有掌握的知识和技巧。现在觉得,写博文真的是一件值得坚持和认真对待的事情,早应该开始。不要问我为什么,当你尝试之后,也就和我一样明白了。

这两篇文章的分析过程肯定有疏漏和不足之处,个人能力有限,希望大家能够理解,并多多指教,非常感谢!我会继续进步!

前面提到过,在每个客户端上,都可以发现5个正常的TCP连接,他们是什么呢?让我们重新回到Jedis。

在《Redis Sentinel的CPU占有率长期接近的问题 一》中,我们提到Jedis SentinelPool会为每一个Sentinel建立一个MasterListener线程,该线程用来主从切换,保证客户端的Jedis句柄始终对应在Master上。在这里,即会有5个MasterListener来对应5个Sentinel。

其实,MasterListener的功能根据Redis的pub sub功能实现的。MasterListener线程会去+switch-消息,该消息会在节点地址改变时产生,一旦产生,MasterListener就重新初始化连接池,保证客户端使用的jedis句柄始终关联到Master上。

如何实现功能呢,我们需要查看subscribe函数的底层实现,它实际使用client.setTimeoutInfinite()->connect建立了一个TCP连接,然后使用JedisPubSub的proceed方法去频道,并且无限循环的读取的信息。

在procee的方法中,实际先通过subscribe频道,然后调用process方法读取信息。

其实,subscribe函数就是简单的向发送了一个SUBSCRIBE命令。

而process函数,篇幅较长,此处省略,其主要功能就是以无限循环的方式不断地读取信息

综上,MasterListener线程会向Sentinel创建+switch-频道的TCP连接,并且会do while循环读取该频道信息。如果或读取过程中出现Tcp连接异常,则释放Jedis句柄,然后等待5000ms 后重新创建Jedis句柄进行。当然,这个过程会在一个循环之中。

至此,也就解释了为何每个业务客户端和Sentinel上,都有5个长期保持的、状态正常的TCP连接的原因了。

linux里安装好系统没有redis.conf怎么解决,而且我也在宝塔里装过一次也没有显示

[root@localhost ~]# cp redis_cluster/7001/redis.conf redis_cluster/7003/

linux下安装Redis[root@localhost ~]# vi redis_cluster/7003/redis.conf方式方法有很多

常用的有使用包管理器安装,比如yum apt 等,源码编译安装

使用包管理器安装的Redis 默认的配置文件在/etc/下

源码编译安装的就在源码目录下

只要自己仔细找找是肯定有的

如果实在找不到 可以手动创建 该配置文件 然后启动的时候 指定即可

希望可以帮助你 请采纳 谢谢

redis阻塞了怎么办

使用物理机;

单线程你别阻塞,Redis时延问题分析及应对

Redis的循环在一个线程中处理,作为一个单线程程序,重要的是要保证处理的时延短,这样,循环中的后续任务才不会阻塞;

耗时长的命令造成阻塞

keys、sort等命令

keys命令用于查找所有符合给定模式 pattern 的 key,时间复杂度为O(N), N 为数据库中 key 的数量。当数据库中的个数达到千万时,这个命令会造成读写线程阻塞数秒;

解决方案:

在架构设计中,有“分流”一招,说的是将处理快的请求和处理慢的请求分离来开,否则,慢的影响到了快的,让快的也快不起来;这在redis的设计中体现的非常明显,redis的纯内存作,epoll非阻塞IO处理,这些快的放在一个线程中搞定,而持久化,AOF重写、Master-sle同步数据这些耗时的作就单开一个进程来处理,不要慢的影响到快的;

embers命令

embers命令用于获取全集,时间复杂度为O(N),N为中的数量;

解决方案:

如果不容易将划分为多个子,而坚持用一个大来存储,那么在取的时候可以考虑使用SRANDMEMBER key [count];随机返回中的指定数量,当然,如果要遍历中的所有元素,这个命令就不适合了;

se命令

se命令使用处理线程进行数据的持久化;当数据量大的时候,会造成线程长时间阻塞(我们的生产上,reids内存中1个G保存需要12s左右),整个redis被block;

解决方案:

fork产生的阻塞

在redis需要执行耗时的作时,会新建一个进程来做,比如数据持久化bgse:

类似的,以下这些作都有进程fork;

Master向sle首次同步数据:当结点收到sle结点来的syn同步请求,会生成一个新的进程,将内存数据dump到文件上,然后再同步到sle结点中;

AOF日志重写:使用AOF持久化方式,做AOF文件重写作会创建新的进程做重写;(重写并不会去读已有的文件,而是直接使用内存中的数据写成归档日志);

解决方案:

控制每个redis实例的内存量;

使用大内存页,默认内存页使用4KB,这样,当使用40G的内存时,页表就有80M;而将每个内存页扩大到4M,页表就只有80K;这样页表几乎没有阻塞,同时也会提高快速页表缓冲TLB(translation lookaside buffer)的命中率;但大内存页也有问题,在写时时,只要一个页快中任何一个元素被修改,这个页块都需要一份(COW机制的粒度是页面),这样在写时期间,会耗用更多的内存空间;

杜绝新进程的产生,不使用持久化,不在主结点上提供查询;实现起来有以下方案:

2) -sle:在主结点上开持久化,主结点不对外提供查询,查询由sle结点提供,从结点不提供持久化;这样,所有的fork耗时的作都在主结点上,而查询请求由sle结点提供;

如果使用的Sentinel将从升级为主,整体实现就相对复杂了;需要更改可用从的ip配置,将其从可查询结点中剔除,让前端的查询负载不再落在新主上;然后,才能放开sentinel的切换作,这个前后关系需要保证;

持久化造成的阻塞

执行持久化(AOF / RDB snapshot)对系统性能有较大影响,特别是结点上还有其它读写磁盘的作时(比如,应用服务和redis服务部署在相同结点上,应用服务实时记录进出报日志);应尽可能避免在IO已经繁重的结点上开Redis持久化;

子进程持久化时,子进程的write和主进程的fsync冲突造成阻塞

在开启了AOF持久化的结点上,当子进程执行AOF重写或者RDB持久化时,出现了Redis查询卡顿甚至长时间阻塞的问题, 此时, Redis无法提供任何读写作;

原因分析:

redis.conf中是这么说的:

解决方案:

子进程AOF重写时,系统的sync造成主进程的write阻塞

我们来梳理下:

产生1)的原因:这是redis2.6.12之前的问题,AOF rewrite时一直埋头的调用write(2),由系统自己去触发sync。>>> Performing hash slots allocation on 6 nodes...

解决方案:

另外,Redis当发现当前正在写的文件有在执行fdatasync(2)时,就先不调用write(2),只存在cache里,免得被block。但如果已经超过两秒都还是这个样子,则会强行执行write(2),即使redis会被block住。

AOF重写完成后合并数据时造成的阻塞

在bgrewriteaof过程中,所有新来的写入请求依然会被写入旧的AOF文件,同时放到AOF buffer中,当rewrite完成后,会在主线程把这部分内容合并到临时文件中之后才rename成新的AOF文件,所以rewrite过程中会不断打印"Background AOF buffer size: 80 MB, Background AOF buffer size: 180 MB",要这部分的日志。这个合并的过程是阻塞的,如果产生了280MB的buffer,在100MB/s的传统硬盘上,Redis就要阻塞2.8秒;

解决方案:

求助linuxRedis单机多节点集群实验报错

步:安装Redis

前面已经安装过了 不解释,

Reids安装包里有个集群工具,要到/usr/local/bin里去

cp redis-3.2.9/src/redis-trib.rb /usr/local/bin

第二步:修改配置,创建节点

我们现在要搞六个节点,三主三从,

端口规定分别是7001,7002,7003,7004,7005,7006

我们先在root目录下新建一个redis_cluster目录,然后该目录下再创建6个目录,

分别是7001,7002,7003,7004,7005,7006,用来存在redis配置文件;

这里我们要使用redis集群,要先修改redis的配置文件redis.conf

mkdir redis_cluster 新建目录

[root@localhost ~]# cd redis_cluster/

[root@localhost redis_cluster]# mkdir 7001 7002 7003 7004 7005 7006

[root@localhost redis_cluster]# ll

总用量 0

drwxr-xr-x. 2 root root 6 7月 27 17:18 7001

drwxr-xr-x. 2 root root 6 7月 27 17:18 7002

drwxr-xr-x. 2 root root 6 7月 27 17:18 7003

drwxr-xr-x. 2 root root 6 7月 27 17:18 7004

drwxr-xr-x. 2 root root 6 7月 27 17:18 7005

drwxr-xr-x. 2 root root 6 7月 27 17:18 7006

[root@localhost redis_cluster]#

先一份配置文件到7001目录下

[root@localhost redis_cluster]# cd

[root@localhost ~]# cp redis-3.2.9/redis.conf redis_cluster/7001/

我们修改下这个配置文件

vi redis_cluster/7001/redis.conf

修改一下几个

port 7001 //六个节点配置文件分别是7001-7006

daemonize yes //redis后台运行

pidfile /var/run/redis_7001.pid //pidfile文件对应7001-7006

cluster-enabled yes //开启集群

cluster-config-file nodes_7001.conf //保存节点配置,自动创建,自动更新对应7001-7006

cluster-node-timeout 5000 //集群超时时间,节点超过这个时间没反应就断定是宕机

appendonly yes //存储方式,aof,将写作记录保存到日志中

7001下的修改完后,我们把7001下的配置分别到7002-7006 然后对应的再修改下配置即可;

[root@localhost ~]# cp redis_cluster/7001/redis.conf redis_cluster/7002/

[root@localhost ~]# cp redis_cluster/7001/redis.conf redis_cluster/7004/

[root@localhost ~]# cp redis_cluster/7001/redis.conf redis_cluster/7005/

[root@localhost ~]# cp redis_cluster/7001/redis.conf redis_cluster/7006/

[root@localhost ~]# vi redis_cluster/7002/redis.conf

[root@localhost ~]# vi redis_cluster/7004/redis.conf

[root@localhost ~]# vi redis_cluster/7005/redis.conf

[root@localhost ~]# vi redis_cluster/7006/redis.conf

编辑后面5个配置文件,把 port ,pidfile,cluster-config-file 分别修改下即可;

第三步:启动六个节点的redis

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7001/redis.conf

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7002/redis.conf

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7003/redis.conf

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7004/redis.conf

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7005/redis.conf

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7006/redis.conf

启动六个节点

[root@localhost ~]# ps -ef | grep redis

查找下redis进程

root 9501 1 0 17:38 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]

root 9512 1 0 17:45 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:7002 [cluster]

root 9516 1 0 17:45 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]

root 9520 1 0 17:45 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:7004 [cluster]

root 9524 1 0 17:45 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:7005 [cluster]

root 9528 1 0 17:45 ? 00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]

说明都启动成功了

第四步:创建集群

redis提供了redis-trib.rb工具,步里已经房到里bin下 ;

但是在使用之前 需要安装ruby,以及redis和ruby连接

yum -y install ruby ruby-dl rubygems rpm-build

gem install redis

redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

创建集群

[root@localhost ~]# redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

>>> Creating cluster

Using 3 s:

127.0.0.1:7001

127.0.0.1:7002

127.0.0.1:7003

Adding replica 127.0.0.1:7004 to 127.0.0.1:7001

Adding replica 127.0.0.1:7005 to 127.0.0.1:7002

Adding replica 127.0.0.1:7006 to 127.0.0.1:7003

M: bfcfcdc304b011023fa568e044ea23ea6bc03c3c 127.0.0.1:7001

slots:0-5460 (5461 slots)

M: d61e66e49e669b99d801f22f6461172696fdd1c9 127.0.0.1:7002

slots:5461-10922 (5462 slots)

M: aa6bc3f1e1174c3a9c01882584707c2408ec18 127.0.0.1:7003

S: 7908a60306333c5d7c7c5e7ffef44bdf947ef0a4 127.0.0.1:7004

replicates bfcfcdc304b011023fa568e044ea23ea6bc03c3c

S: 1d2341fd3b79ef0fccb8e3a052bba141337c6cdd 127.0.0.1:7005

replicates d61e66e49e669b99d801f22f6461172696fdd1c9

replicates aa6bc3f1e1174c3a9c01882584707c2408ec18

Can I set the above configuration? (type 'yes' to accept):

从运行结果看 主节点就是7001 7002 7003 从节点分别是7004 7005 7006

7001分配到的哈希槽是 0-5460

7002分配到的哈希槽是 5461-10922

7003分配到的哈希槽是 10923-16383

问我们是否接受上面的设置,输入yes 就表示接受,我们输入yes

然后显示:

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join......

>>> Performing Cluster Check (using node 127.0.0.1:7001)

M: bfcfcdc304b011023fa568e044ea23ea6bc03c3c 127.0.0.1:7001

slots:0-5460 (5461 slots)

1 additional replica(我们知道,Sentinel是特殊模式的Redis,我们无法使用config set命令去修改其配置,包括tcpkeepalive 参数。所以,当Sentinel启动后,Sentinel也使用默认的tcpkeepalive ==0这个设置,不会启用tcpkeepalive ,与客户端的TCP连接都没有保活机制。也就是说,Sentinel不会主动去释放连接,哪怕是失效连接。s)

replicates aa6bc3f1e1174c3a9c01882584707c2408ec18

M: d61e66e49e669b99d801f22f6461172696fdd1c9 127.0.0.1:7002

slots:5461-10922 (5462 slots)

1 additional replica(s)

S: 1d2341fd3b79ef0fccb8e3a052bba141337c6cdd 127.0.0.1:7005

replicates d61e66e49e669b99d801f22f6461172696fdd1c9

M: aa6bc3f1e1174c3a9c01882584707c2408ec18 127.0.0.1:7003

1 additional replica(s)

S: 7908a60306333c5d7c7c5e7ffef44bdf947ef0a4 127.0.0.1:7004

replicates bfcfcdc304b011023fa568e044ea23ea6bc03c3c

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

显示配置哈希槽,以及集群创建成功,可以用了;

第五步:集群数据测试

我们先连接任意一个节点,然后添加一个key:

redis-cli是redis默认的客户端工具,启动时加上`-c`参数,`-p`指定端口,就可以连接到集群。

连接任意一个节点端口:

[root@localhost ~]# /usr/local/redis/bin/redis-cli -c -p 7002

127.0.0.1:7002>

我们连接7002

127.0.0.1:7002> set xxx 'fdafda'

-> Redirected to slot [4038] located at 127.0.0.1:7001

OK

前面说过Redis Cluster值分配规则,所以分配key的时候,它会使用CRC16(‘my_name’)%16384算法,来计算,将这个key 放到哪个节点,这里分配到了4038slot 就分配到了7001(0-5460)这个节点上。所以有:

Redirected to slot [4038] located at 127.0.0.1:7001

我们从其他集群节点 ,都可以获取到数据

127.0.0.1:7001> exit

[root@localhost ~]# /usr/local/redis/bin/redis-cli -c -p 7005

127.0.0.1:7005> get xxx

-> Redirected to slot [4038] located at 127.0.0.1:7001

"fdafda"

127.0.0.1:7001>

第六步:集群宕机测试

假如我们干掉一个节点,比如7002 这个主节点

root 9501 1 0 17:38 ? 00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]

root 9512 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7002 [cluster]

root 9516 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]

root 9520 1 0 17:45 ? 00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7004 [cluster]

root 9524 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7005 [cluster]

root 9528 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]

root 9601 2186 0 18:12 pts/0 00:00:00 grep --color=auto redis

[root@localhost ~]# kill -9 9512

root 9501 1 0 17:38 ? 00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]

root 9516 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]

root 9520 1 0 17:45 ? 00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7004 [cluster]

root 9524 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7005 [cluster]

root 9528 1 0 17:45 ? 00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]

root 9603 2186 0 18:12 pts/0 00:00:00 grep --color=auto redis

[root@localhost ~]#

然后再来看下集群的情况

redis-trib.rb check 127.0.0.1:70如下所示为MasterListener的线程函数,它会在一个无限循环中不断的创建Jedis句柄,利用该句柄去+switch-消息,只要发生了主从切换,就会触发onMessage。01

>>> Performing Cluster Check (using node 127.0.0.1:7001)

M: bfcfcdc304b011023fa568e044ea23ea6bc03c3c 127.0.0.1:7001

slots:0-5460 (5461 slots)

1 additional replica(s)

replicates aa6bc3f1e1174c3a9c01882584707c2408ec18

M: 1d2341fd3b79ef0fccb8e3a052bba141337c6cdd 127.0.0.1:7005

slots:5461-10922 (5462 slots)

0 additional replica(s)

M: aa6bc3f1e1174c3a9c01882584707c2408ec18 127.0.0.1:7003

1 additional replica(s)

S: 7908a60306333c5d7c7c5e7ffef44bdf947ef0a4 127.0.0.1:7004

replicates bfcfcdc304b011023fa568e044ea23ea6bc03c3c

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

我们发现 7005本来是从节点,由于他对应的主节点挂了,就自动变成主节点,所有会有一个说明

All 16384 slots covered. 所有哈希槽都可覆盖了; 集群可以正常使用;

假如我们把7005也干掉,试试看

root 9501 1 0 17:38 ? 00:00:03 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]

root 9516 1 0 17:45 ? 00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]

root 9520 1 0 17:45 ? 00:00:03 /usr/local/redis/bin/redis-server 127.0.0.1:7004 [cluster]

root 9528 1 0 17:45 ? 00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]

root 9610 2186 0 18:16 pts/0 00:00:00 grep --color=auto redis

[root@localhost ~]#

查看下集群情况

redis-trib.rb check 127.0.0.1:7001

这里我们发现 出事了,因为主从节点都挂了 所以有一部分哈希槽没得分配,一句

[ERR] Not all 16384 slots are covered by nodes. 没有安全覆盖;

所以不能正常使用集群;

linux里安装好系统没有redis.conf怎么解决,而且我也在宝塔里装过一次也没有显示

这时,也许你会想到,是否因为系统文件描述符的限制导致Sentinel无法建立更多的Socket,从而产生“Too many open files”的错误。所以,马上在Sentinel上运行cat /proc/sys/fs/file-max,发现:

linux下安装Redis方式方法有很多

[root@localhost ~]# ps -ef | grep redis

常用的有使用包管理器安装,比如yum apt 等,源码编译安装

使用包管理器安装的Redis 默认的配置文件在/etc/下

源码编译安装的就在源码目录下

只要自己仔细找找是肯定有的

如果实在找不到 可以手动创建 该配置文件 然后启动的时候 指定即可

希望可以帮助你 请采纳 谢谢

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 12345678@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息