1、安装编译工具2、安装tcl组件包(安装Redis需要tcl支持)3、安装Redis4、设置redis开机启动 5、设置redis配置文件参数6、测试redis数据库7、通过php程序连接redis数据库 #php必须先安装Redis扩展至此,Linux下Redis服务器安装配置完成。
Redis复制流程概述Redis的复制功能是完全建立在之前我们讨论过的基于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你的系统内存容量规划,原因可以参考我上一篇文章中提到的Redis磁盘IO问题。
Redis复制流程在Slave和Master端各自是一套状态机流转,涉及的状态信息是:
Slave 端:
REDIS_REPL_NONEREDIS_REPL_CONNECTREDIS_REPL_CONNECTED
Master端:
REDIS_REPL_WAIT_BGSAVE_STARTREDIS_REPL_WAIT_BGSAVE_ENDREDIS_REPL_SEND_BULKREDIS_REPL_ONLINE
整个状态机流程过程如下:
Slave端在配置文件中添加了slave of指令,于是Slave启动时读取配置文件,初始状态为REDIS_REPL_CONNECT。
Slave端在定时任务serverCron(Redis内部的定时器触发事件)中连接Master,发送sync命令,然后阻塞等待master发送回其内存快照文件(最新版的Redis已经不需要让Slave阻塞)。
Master端收到sync命令简单判断是否有正在进行的内存快照子进程,没有则立即开始内存快照,有则等待其结束,当快照完成后会将该文件发送给Slave端。
Slave端接收Master发来的内存快照文件,保存到本地,待接收完成后,清空内存表,重新读取Master发来的内存快照文件,重建整个内存表数据结构,并最终状态置位为 REDIS_REPL_CONNECTED状态,Slave状态机流转完成。
Master端在发送快照文件过程中,接收的任何会改变数据集的命令都会暂时先保存在Slave网络连接的发送缓存队列里(list数据结构),待快照完成后,依次发给Slave,之后收到的命令相同处理,并将状态置位为 REDIS_REPL_ONLINE。
整个复制过程完成,流程如下图所示:
Redis复制机制的缺陷
从上面的流程可以看出,Slave从库在连接Master主库时,Master会进行内存快照,然后把整个快照文件发给Slave,也就是没有象MySQL那样有复制位置的概念,即无增量复制,这会给整个集群搭建带来非常多的问题。
比如一台线上正在运行的Master主库配置了一台从库进行简单读写分离,这时Slave由于网络或者其它原因与Master断开了连接,那么当Slave进行重新连接时,需要重新获取整个Master的内存快照,Slave所有数据跟着全部清除,然后重新建立整个内存表,一方面Slave恢复的时间会非常慢,另一方面也会给主库带来压力。
所以基于上述原因,如果你的Redis集群需要主从复制,那么最好事先配置好所有的从库,避免中途再去增加从库。
Cache还是Storage
在我们分析过了Redis的复制与持久化功能后,我们不难得出一个结论,实际上Redis目前发布的版本还都是一个单机版的思路,主要的问题集中在,持久化方式不够成熟,复制机制存在比较大的缺陷,这时我们又开始重新思考Redis的定位:Cache还是Storage?
如果作为Cache的话,似乎除了有些非常特殊的业务场景,必须要使用Redis的某种数据结构之外,我们使用Memcached可能更合适,毕竟Memcached无论客户端包和服务器本身更久经考验。
如果是作为存储Storage的话,我们面临的最大的问题是无论是持久化还是复制都没有办法解决Redis单点问题,即一台Redis挂掉了,没有太好的办法能够快速的恢复,通常几十G的持久化数据,Redis重启加载需要几个小时的时间,而复制又有缺陷,如何解决呢?
Redis可扩展集群搭建1 主动复制避开Redis复制缺陷。
既然Redis的复制功能有缺陷,那么我们不妨放弃Redis本身提供的复制功能,我们可以采用主动复制的方式来搭建我们的集群环境。
所谓主动复制是指由业务端或者通过代理中间件对Redis存储的数据进行双写或多写,通过数据的多份存储来达到与复制相同的目的,主动复制不仅限于用在Redis集群上,目前很多公司采用主动复制的技术来解决MySQL主从之间复制的延迟问题,比如Twitter还专门开发了用于复制和分区的中间件gizzard(>非常感谢您的提问。当微服务连接不上Redis时,会根据代码实现的逻辑来决定是否直接访问数据库。一般来说,如果代码中没有对Redis连接失败的情况进行处理,那么微服务会直接访问数据库。但是,如果代码中有对Redis连接失败的情况进行了处理,那么就会根据处理逻辑来决定是否直接访问数据库。因此,我们建议在代码中对Redis连接失败的情况进行处理,以确保系统的稳定性和可靠性。同时,我们也建议在系统设计时,考虑到Redis的可靠性和高可用性,采用集群或者主从复制等方式来保证Redis的可用性。希望我的回答能够帮到您,如果您还有其他问题,欢迎继续提问。CentOS下Redis服务器安装配置连接教程
>这问题需要一步一步排查:
首先,你可以在redis所在的虚拟机上,写一个py脚本,看看本地 *** 作redis是否有问题;
其次,确认一下redis虚拟机上的iptables是不是有限制,最简单粗暴的方式就是先临时禁用一下iptables试试看;
再次,就是要看看你整个的环境了,如果是在云环境上,云环境本身会有对于端口的限制,看看是不是有可能影响到。
过程中也许还有其他中可能,总之步骤就是先本地,再远程,先单体,后环境。希望可以帮到你!构建 Redis
redis 目前没有官方 RPM 安装包,我们需要从源代码编译,而为了要编译就需要安装 Make 和 GCC。
如果没有安装过 GCC 和 Make,那么就使用 yum 安装。
yum install gcc make
从官网下载 tar 压缩包。
curl -o redis-304targz
解压缩。
tar zxvf redis-304targz
进入解压后的目录。
cd redis-304
使用Make 编译源文件。
make
安装
进入源文件的目录。
cd src
复制 Redis 的服务器和客户端到 /usr/local/bin。
cp redis-server redis-cli /usr/local/bin
最好也把 sentinel,benchmark 和 check 复制过去。
cp redis-sentinel redis-benchmark redis-check-aof redis-check-dump /usr/local/bin
创建redis 配置文件夹。
mkdir /etc/redis
在/var/lib/redis 下创建有效的保存数据的目录
mkdir -p /var/lib/redis/6379
系统参数
为了让 redis 正常工作需要配置一些内核参数。
配置 vmovercommit_memory 为1,这可以避免数据被截断,详情见此。
sysctl -w vmovercommit_memory=1
修改 backlog 连接数的最大值超过 redisconf 中的 tcp-backlog 值,即默认值511。你可以在kernelorg 找到更多有关基于 sysctl 的 ip 网络隧道的信息。
sysctl -w netcoresomaxconn=512
取消对透明巨页内存(transparent huge pages)的支持,因为这会造成 redis 使用过程产生延时和内存访问问题。
echo never > /sys/kernel/mm/transparent_hugepage/enabled
redisconf
redisconf 是 redis 的配置文件,然而你会看到这个文件的名字是 6379conf ,而这个数字就是 redis 监听的网络端口。如果你想要运行超过一个的 redis 实例,推荐用这样的名字。
复制示例的 redisconf 到 /etc/redis/6379conf。
cp redisconf /etc/redis/6379conf
现在编辑这个文件并且配置参数。
vi /etc/redis/6379conf
daemonize
设置 daemonize 为 no,systemd 需要它运行在前台,否则 redis 会突然挂掉。
daemonize no
pidfile
设置 pidfile 为 /var/run/redis_6379pid。
pidfile /var/run/redis_6379pid
port
如果不准备用默认端口,可以修改。
port 6379
loglevel
设置日志级别。
loglevel notice
logfile
修改日志文件路径。
logfile /var/log/redis_6379log
dir
设置目录为 /var/lib/redis/6379
dir /var/lib/redis/6379
安全
下面有几个可以提高安全性的 *** 作。
Unix sockets
在很多情况下,客户端程序和服务器端程序运行在同一个机器上,所以不需要监听网络上的 socket。如果这和你的使用情况类似,你就可以使用 unix socket 替代网络 socket,为此你需要配置 port 为0,然后配置下面的选项来启用 unix socket。
设置 unix socket 的套接字文件。
unixsocket /tmp/redissock
限制 socket 文件的权限。
unixsocketperm 700
现在为了让 redis-cli 可以访问,应该使用 -s 参数指向该 socket 文件。
redis-cli -s /tmp/redissock
requirepass
你可能需要远程访问,如果是,那么你应该设置密码,这样子每次 *** 作之前要求输入密码。
requirepass "bTFBx1NYYWRMTUEyNHhsCg"
rename-command
想象一下如下指令的输出。是的,这会输出服务器的配置,所以你应该在任何可能的情况下拒绝这种访问。
CONFIG GET
为了限制甚至禁止这条或者其他指令可以使用 rename-command 命令。你必须提供一个命令名和替代的名字。要禁止的话需要设置替代的名字为空字符串,这样禁止任何人猜测命令的名字会比较安全。
rename-command FLUSHDB "FLUSHDB_MY_SALT_G0ES_HERE09u09u"rename-command FLUSHALL ""rename-command CONFIG "CONFIG_MY_S4LT_GO3S_HERE09u09u"第一:非集群状态下
非集群状态下用Jedis获取Redis连接,得到Jedis对象即可,一共有两种:
1利用Jedis构造器,仅限用于测试,在实际项目中肯定是用JedisPool。
Jedis(String host);
Jedis(String host , int port);
2利用JedisPool
主要是利用Jedis jedis=jedisPoolgetResource();
JedisPool有N多个构造器,常用的构造器参数有GenericObjectPoolConfig poolConfig,String host,int port,int timeout,String password,创建GenericObjectPoolConfig对象时我们一般用其子类JedisPoolConfig (redisclientsjedisJedisPoolConfig),timeout是连接redis服务器的超时时间,以毫秒为单位,一般设置为0,如果不设为0,则不可设置太小,如果设成1、2,那么可能因为网络原因在1毫秒、2毫秒之内没有连上服务器而报错。见下例:
[java] view plain copy
public static void main(String[] args) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最大连接数
poolConfigsetMaxTotal(2);
// 最大空闲数
poolConfigsetMaxIdle(2);
// 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常:
// Could not get a resource from the pool
poolConfigsetMaxWaitMillis(1000);
JedisPool pool = new JedisPool(poolConfig, "19216883128", 6379, 0, "123");
Jedis jedis = null;
try {
for (int i = 0; i < 5; i++) {
jedis = poolgetResource();
jedisset("foo" + i, "bar" + i);
Systemoutprintln("第" + (i + 1) + "个连接, 得到的值为" + jedisget("foo" + i));
// 用完一定要释放连接
jedisclose();
}
} finally {
poolclose();
}
}
如上,创建出一个JedisPool对象,然后调用其getResource()方法获取redis连接即可,之后就可以调用Jedis API *** 作redis了。jedis连接用完要释放即close,如果不close,则产生的连接会越来越多,当达到了最大连接数,再想获得连接,就会等待,当超过了最大等待时间后就会报异常。
第二:集群状态下
集群状态下用Jedis获取redis连接,是得到JedisCluster对象,之后对redis进行 *** 作都是用此对象的方法进行的:
[java] view plain copy
public static void main(String[] args) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最大连接数
poolConfigsetMaxTotal(1);
// 最大空闲数
poolConfigsetMaxIdle(1);
// 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常:
// Could not get a resource from the pool
poolConfigsetMaxWaitMillis(1000);
Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
nodesadd(new HostAndPort("19216883128", 6379));
nodesadd(new HostAndPort("19216883128", 6380));
nodesadd(new HostAndPort("19216883128", 6381));
nodesadd(new HostAndPort("19216883128", 6382));
nodesadd(new HostAndPort("19216883128", 6383));
nodesadd(new HostAndPort("19216883128", 6384));
JedisCluster cluster = new JedisCluster(nodes, poolConfig);
String name = clusterget("name");
Systemoutprintln(name);
clusterset("age", "18");
Systemoutprintln(clusterget("age"));
try {
clusterclose();
} catch (IOException e) {
eprintStackTrace();
}
}
用集群时,好像没有办法设置集群的参数,比如最大连接数,虽然在创建JedisCluster 对象时传了JedisPoolConfig对象进去,但是JedisPoolConfig对象中的设置是不生效的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)