文档章节

redis配置及和spring的各种结合

whaon
 whaon
发布于 2016/07/14 11:00
字数 1931
阅读 1203
收藏 11

下载

wget http://download.redis.io/releases/redis-3.2.1.tar.gz

编译安装运行

make && make install 如果出错使用 make MALLOC=libc && make install 安装成功后,会自动把一些可执行文件复制到环境变量/usr/local/bin/下

redis-benchmark
redis-check-aof
redis-check-rdb
redis-cli
redis-sentinel
redis-server

redis根目录下有2个重要的配置文件

  1. redis.conf #redis本身的配置文件
  2. sentinel.conf #容灾部署的配置文件(哨兵)

redis是可以在客户端执行一些配置命令,并且是可以反写入配置文件的,所以有时候发现配置文件默默的被修改了千万不要惊讶

可以直接使用这2个配置文件,我的习惯是复制这2个文件到/etc/目录下,然后启动的时候指定/etc/下的配置文件

配置redis.conf

bind 127.0.0.1 #这一行注释掉,这样其他机器才可以访问
port 6379 #修改端口号
daemonize yes #改为后台运行
logfile ""  #指定日志文件的路径
databases 16 #数据库的数目,可以对比mysql来理解,默认是16,不同db的key不会冲突,可以在客户端redis-cli中用select 8来切换db
dbfilename "dump.rdb" #RDB持久化的文件名称
requirepass "foobared" #需要设置复杂一点的密码
maxmemory 3gb #设置给redis使用的最大内存
maxmemory-policy volatile-lru #最大内存策略
hash-max-ziplist-entries 512 #以下都是一些内存优化策略
hash-max-ziplist-value 64
list-max-ziplist-size -2
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

# 禁用高危的命令
rename-command FLUSHALL ""
rename-command CONFIG   ""
rename-command EVAL     ""

运行redis-server /etc/redis.conf

持久化

支持2种,RDB和AOF,默认开启RDB,关闭AOF,根据实际情况进行配置 RDB建议一定开启,开启后,redis内存中的数据会保存到dump.rdb,并且所有的db共享,可以对该文件定期备份,redis重启后,会读取dump.rdb里面的数据到内存 手动执行save命令可以立即把内存中的数据保存到db中

主备

2台redis,一台master,一台slave,只需在slave上加入如下配置

slaveof <masterip> <masterport>
masterauth foobared
slave-read-only yes #建议开启

这样在master上操作的数据就会同步到slave,在slave上修改的数据不会同步到master,并且slave重启后,会先执行flushall,然后重新从master同步,从以下日志也可以看粗来

28884:S 14 Jul 01:52:48.269 * Full resync from master: 13a3a2cb882f2b18e8d689b19ab5db711301ca2f:4682895
28884:S 14 Jul 01:52:48.438 * MASTER <-> SLAVE sync: receiving 167 bytes from master
28884:S 14 Jul 01:52:48.439 * MASTER <-> SLAVE sync: Flushing old data
28884:S 14 Jul 01:52:48.439 * MASTER <-> SLAVE sync: Loading DB in memory
28884:S 14 Jul 01:52:48.439 * MASTER <-> SLAVE sync: Finished with success

容灾

  1. 可以用传统的keepalived
  2. 使用zookeeper,需要在redis启动时操作zookeeper
  3. 使用redis自带的sentinel机智,推荐,安装完redis后就会有redis-sentinel这个可执行文件,一般会在运行redis的机器上都运行sentinel
配置sentinel.conf
daemonize yes #也需要加上
port 7031 #修改端口
protected-mode no #这个必须加上,否则其他机器连不上
sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs <master-name> <numslaves>
sentinel auth-pass <master-name> <password>

运行redis-sentinel /etc/sentinel.conf 执行redis-cli -p sentinel-port,接着执行 SENTINEL masters #来查看master的信息,也可以执行以下命令 SENTINEL get-master-addr-by-name mymaster #jedis就是通过这种方式来找到slave的 这样配置好后,如果master挂了,过了一小段时间后,slave会提升为master,并且之前的master如果恢复后,会自己变成slave,配置文件redis.conf也会被修改 **注意:**sentinel本身是没有密码的,只要配置了protected-mode no客户端就可以随意访问,但是master是需要密码的。上面的配置sentinel auth-pass <master-name> <password>不是sentinel的密码,而是发生主备切换时sentinel修改本地redis.conf配置时所需要的密码。

使用jedis来操作redis

可以使用纯jedis来操作

maven

<dependency>  
      <groupId>redis.clients</groupId>  
      <artifactId>jedis</artifactId>  
      <version>2.8.1</version>  
</dependency>

会自动引入commons-pool

和spring结合(不使用spring-data-redis,不使用RedisTemplate)

1.直接使用pool

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="50" />
		<property name="maxIdle" value="10" />
		<property name="minIdle" value="0" />
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy">
		<constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
		<constructor-arg name="host" value="172.16.154.233"></constructor-arg>
		<constructor-arg name="port" value="6379"></constructor-arg>
		<constructor-arg name="timeout" value="30000"></constructor-arg>
		<constructor-arg name="password" value="foobared"></constructor-arg>
</bean>

2.使用sentinel pool

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="50" />
		<property name="maxIdle" value="10" />
		<property name="minIdle" value="0" />
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisSentinelPool">
		<constructor-arg index="0" value="mymaster" />
		<constructor-arg index="1">
			<set>
				<value>172.16.154.232:7031</value>
				<value>172.16.154.233:7031</value>
			</set>
		</constructor-arg>
		<constructor-arg index="2" ref="jedisPoolConfig" />
		<constructor-arg index="3" value="600000" />
		<constructor-arg index="4" value="foobared" />
	</bean>

这样,取得jedisPool这个bean,然后调用getResource()方法即可获得Jedis这个操作类

和spring结合(使用spring-data-redis,使用RedisTemplate)

maven

<dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.7.2.RELEASE</version>
</dependency>

配置

	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="50" />
		<property name="maxIdle" value="10" />
		<property name="minIdle" value="0" />
	</bean>
	<bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
		<constructor-arg name="master" value="mymaster"></constructor-arg>
		<constructor-arg name="sentinelHostAndPorts">
			<set>
			    <value>172.16.154.232:7031</value>
			    <value>172.16.154.233:7031</value>
			</set>
		</constructor-arg>
	</bean>
	<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
		<constructor-arg name="sentinelConfig" ref="sentinelConfig" />
		<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
		<property name="password" value="foobared"></property>
	</bean>
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>
	<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>

注意配置了2个template,RedisTemplate和StringRedisTemplate RedisTemplate默认使用了JdkSerializationRedisSerializer,是通过ObjectInputStream和ObjectOutputStream来实现序列化,而且本身的操作不是很方便,虽然实现了模板模式,但是很多都是通过执行execute,自己仍然需要实现匿名内部类,我们可通过执行opsForXXX来获得一些比较方便的操作类来进行操作,最典型的就是执行opsForValue()来获得ValueOperations,该类提供了一些比较方便的API

public interface ValueOperations<K, V> {

	void set(K key, V value);

	/**
	 * Set {[[[[[@code](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo) key} to hold the string {[[[[[@code](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo) value} until {[[[[[@code](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo)](http://my.oschina.net/codeo) timeout}.
	 * 
	 * [[[[[@param](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379) key
	 * [[[[[@param](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379)](http://my.oschina.net/u/2303379) value
	 * @param timeout
	 * @param units
	 * @see http://redis.io/commands/set
	 */
	void set(K key, V value, long timeout, TimeUnit unit);

	Boolean setIfAbsent(K key, V value);

	void multiSet(Map<? extends K, ? extends V> m);

	Boolean multiSetIfAbsent(Map<? extends K, ? extends V> m);

	V get(Object key);

	V getAndSet(K key, V value);

	List<V> multiGet(Collection<K> keys);

	Long increment(K key, long delta);

	Double increment(K key, double delta);

	Integer append(K key, String value);

	String get(K key, long start, long end);

	void set(K key, V value, long offset);

	Long size(K key);

	RedisOperations<K, V> getOperations();
	
	/**
	 * @since 1.5
	 * @param key
	 * @param offset
	 * @param value
	 * @return
	 */
	Boolean setBit(K key, long offset, boolean value);
	
	/**
	 * @since 1.5
	 * @param key
	 * @param offset
	 * @return
	 */
	Boolean getBit(K key, long offset);
	
}

但是由于默认是使用JdkSerializationRedisSerializer,所以你通过set方法后,在redis-cli中会看不到你想要的结果,比如执行了template.opsForValue().set("r", "r"),但是通过keys *看到的结果是"\xac\xed\x00\x05t\x00\x01r",在redis-cli中执行get r会返回(nil),需要执行get "\xac\xed\x00\x05t\x00\x01r"才能得到结果,并且是"\xac\xed\x00\x05t\x00\x01r",但是通过RedisTemplate是可以正常访问的template.opsForValue().get("r"),因为它会帮你进行序列化和反序列化

再看StringRedisTemplate,StringRedisTemplate是继承RedisTemplate,无非是使用StringRedisSerializer,其他和RedisTemplate一样,该Serializer是使用String类来进行序列化的,和jedis原生的一样,代码如下:

public class StringRedisSerializer implements RedisSerializer<String> {

	private final Charset charset;

	public StringRedisSerializer() {
		this(Charset.forName("UTF8"));
	}

	public StringRedisSerializer(Charset charset) {
		Assert.notNull(charset);
		this.charset = charset;
	}

	public String deserialize(byte[] bytes) {
		return (bytes == null ? null : new String(bytes, charset));
	}

	public byte[] serialize(String string) {
		return (string == null ? null : string.getBytes(charset));
	}
}

使用StringRedisTemplate后,再使用上述的template.opsForValue().set("r", "r")机会得到你想要的比较正常的结果了

spring还提供了一些其他的Serializer,部分如下:

StringRedisSerializer
OxmSerializer
Jackson2JsonRedisSerializer

-------------------------------------------------分割线2017年8月15日17:18:51-------------------------------------------------
最先版本为4.0.1 wget http://download.redis.io/releases/redis-4.0.1.tar.gz

© 著作权归作者所有

共有 人打赏支持
whaon

whaon

粉丝 43
博文 39
码字总数 35115
作品 0
厦门
程序员
Spring Cloud--Honghu Cloud分布式微服务云系统—组件化

Spring Cloud集成项目有很多,下面我们列举一下和Spring Cloud相关的优秀项目,我们的企业架构中用到了很多的优秀项目,说白了,也是站在巨人的肩膀上去整合的。在学习Spring Cloud之前大家必...

itcloud
04/26
0
0
Spring AOP整合redis 实现缓存统一管理

项目使用redis作为缓存数据,但面临着问题,比如,项目A,项目B都用到redis,而且用的redis都是一套集群,这样会带来一些问题。 问题:比如项目A的开发人员,要缓存一些热门数据,想到了red...

豆芽菜橙
08/01
0
0
springboot,redis应用

1、redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。 2、这...

小不点丶
2017/10/20
0
0
使用maven创建一个spring-boot项目-集成springmvc

以下是自己学习spring-boot的过程中整理的笔记。 一、spring-boot介绍 1、Spring-boot跟springframe的关系 spring framework就好比一个大型的电子元件生产公司,它生产的元件性能都很优秀,...

Prepared
06/27
0
0
redis客户端jedis&spring-data-redis源码赏析

背景 本文主要对当下开源流行的redis客户端jedis和spring-data-redis的部分核心源码进行剖析,记录一下怎么去实现一个redis的java客户端以及需要注意些什么。 版本 jedis:v2.9.0、 spring-d...

菜蚜
08/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

谷歌 Fuchsia 上手体验,将取代Android/win10

在手机市场领域,Google表现很抢眼,毫无疑问,Android 至今在移动操作系统的市场份额占据绝对领先地位,但是 Android 仍然存在不少问题,碎片化问题严重,在平板以及大屏幕设备上表现糟糕,...

linux-tao
13分钟前
1
0
List、Array与ArrayList

数组在内存中是连续存储的,所以它的索引速度很快,而且赋值和修改元素也非常快,比如: string[] s=new string[3];//赋值 s[0]="a"; s[1]="b"; s[2]="c";//修改 s[1]="b1"; 但是数组...

shimmerkaiye
16分钟前
0
0
Linux 的Lnmp环境下为mysql添加环境变量

一.问题 在Linux 安装完Lnmp 环境后 , 连接Mysql 告诉没有这条命令 mysql -uroot -p 命令失效 因为是源码安装的,所以会出现这样的的原因 。集成环境是不会出现的。 其实很简单,只需要给m...

15834278076
18分钟前
2
0
apolloxlua include函数

include函数不是单独使用的函数, 他并不是标准库的一部分, 你可以使用include函数将某个后缀为 .aop的文档包含到你的文档流中。 因为include是单独处理流, 所以不会在主处理流程中有所表示...

钟元OSS
22分钟前
0
0
【转载分享】做一名较真的工程师

近些年与我共事过的同事,一定知道我至今仍有一个较真的性格。我会:指出同事所写代码的不当命名问题(并帮助改进);指出同事所写文档中的逻辑混乱问题(并辅以修订);指出同事所写PPT中乱...

HellerZhang
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部