Redis使用,伪集群和单机开发

redis是什么?

redis,开源的基于内存存储的数据结构服务器。可以用来做数据库,高速缓存,以及消息队列代理。

支持数据持久化(内存数据本地化),支持主从备份(高可用,分布式)

存储格式:key-value式存储

可以存储的数据类型:

这里不做详细介绍,官网上有详细的文档,需要的时候查询就可以了 Redis中文网站

简单key-value(string)

set key val

get key

hash


hset key field val
hget key field
hdel key field [field]  删除一个或多个hash表字段
hgetall key   获取哈希表中指定key的所有字段和值
hvals key  获取哈希表中所有的值

list(下标从0开始,负数代表重末尾往前,-1 代表最后一个值的下标)

lpush key val1 [val2]  将一个或者多个值插入列表头部
rpush key val1 [val2] 将一个或者多个值插入列表(从尾部插入)
lindex key index  根据下标查询
llen key    获得列表大小
lrange key start stop   查询指定范围内的元素(如果stop指定为-1或者超过列表最大值,则返回列表所有value,这和python的列表查询方式一致,负数代表从末尾往前数)

set

sadd key member1 [member2]   向集合添加一个或多个成员
scard key    获取集合成员数
sdiff key1 [key2]   获得给定集合的差集
sinter key1[key2]   获得给定集合的交集
smembers key  列出集合所有的成员

zset(有序集合 sorted set ,因为其操作命令都以z开头故有zset之称)

zadd key1 score1 member1 [score2 member2] 向集合中添加一个或者多个成员,或更新已存在成员的score(所谓的有序集合就是可以指定不同的score,按从大到小往下排,该值为整型,可以相同。相同情况下按添加顺序作为顺序)
zrange key start stop [withscores]  通过索引区间返回有序集合指定区间内的成员,加上withscores会连成员对应的score一并查询出来
zrank key member  返回有序集合中指定成员的索引


为什么用redis?

快啊,快到不能呼吸。基于内存的数据库,读取速度110000次/s 写入速度81000次/s    相比mysql几千的吞吐量来说,简直坐了火箭了。

理论上来说硬盘的容量高于内存的容量。数据量过于庞大的话,内存的容量有可能达不到,所以redis常用来做高速缓存,用来提高系统的读取性能,提高系统响应速度。而一些不经常查询的数据就放在关系型数据库中。

怎么用redis?

redis那么好,我们怎么用呢(基于集群)?

1、下载redis,这里提供redis的 windows版本的下载链接。redis官方现不提供windows版本的下载。

2、如果你需要搭建集群的话,需要Ruby的支持,去运行redis提供的Ruby脚本来搭建集群。如果你只使用单机,可以略过此步。这里提供Ruby的windows版本安装地址

3、新建一个目录【redis-cluster】,基于redis有投票机制来判定一个master节点是否挂掉(若有半数的master投票通过,就认为这个master挂掉了。)

知识点:redis集群(redis cluster),分主从(master-slave)数据库,一个主节点(master)可以对应多个从节点(slave)。当有一台master节点挂掉后,通过投票机制来判定这个节点是否真的挂掉了,如果超过半数的master投票通过,则该节点被认为挂掉。问题节点可以灵活地进行主从切换。

4、我们拷贝6个redis放到【redis-cluster】下面,修改其中地配置文件。windows版的配置文件为redis.windows.conf(linux版地为reids.conf)。

①删除redis目录下地nodes.conf,appendonly.aof,dump.rdb(如果有这三个文件地话),让redis后面自动生成。如果不删除,留有旧信息地话会报以下错误。

[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

②找到prot属性,默认为6379。我们把6个redis地端口改为6379-6384

cluster-enabled yes   放开,如果为no改为yes  开启集群支持

④cluster-node-timeout   默认时间为15000毫秒,默认是关闭地,该属性用来判断节点响应超时地时间,如果响应超时则发起投票,判断该节点是否挂掉。

⑤appendonly yes  该属性更改为yes并放开

知识点: nodes.conf 节点配置文件,默认为nodes.conf可以通过修改cluster-config-file name.conf 来配置

redis数据本地化有两种方式:rdb(redis database),aof(append only filed)。rdb属于redis快照方式,每隔一段时间就将内存中地数据保存到本地,性能高,但是数据的安全性得不到保障。  aof 是性能和安全的一个折中办法,默认每隔一秒将redis操作中的写操作,保存到本地。rdb保存的是数据,aof保存的是操作。

5、拷贝一个redis-trib.rb到redis-cluster目录下,这是一个ruby配置redis的脚本文件。除此之外,我们还需要一个redis和ruby的接口工具包  redis-3.0.0.gem

6、将所需的redis全部启动  在每一个reids目录下cmd执行redis-server redis.windows.conf

7、启动ruby命令窗口,切换到redis-cluster目录  运行以下命令,把我们需要的地址都给写上。

redis-trib.rb create --replicas 1 host1:port1 [host2:port2]

出现  Can I set the above configuration? (type'yes' to accept): 填写yes

出现[OK] All nodes agree about slotsconfiguration.代表配置成功

检查集群:可以使用redis-trib.rb check host:port(集群中任意一个节点的地址都可以)

                 也可以使用redis-cli  -h host -p port -c(-c表示以集群方式链接redis,如果不加就是单机的。host,port为集群中任一ip)链接上后 使用 cluster info 命令查看集群信息。

至此。集群就搭建完成了。

其他:


       可以使用redis-trib.rb add-node  new_host:port(新节点) existing_host:existing_port(集群中在运行的节点) 添加一个新节点

  使用redis-trib.rb add-node --slave --master-id nodeid(master-node的id)  new_host:port(新节点) existing_host:existing_port(集群中在运行的节点)   为指定master节点添加一个从节点。

关于槽的概念:总共有16384个槽(0-16383),槽上存数据,槽只存在master节点上。如果添加了新节点,重新分配槽,槽上的数据会随着槽移动走。

单机形式的redis, 配置了port 配置了aof后直接输入命令  redis-server redis.windows.conf  直接就执行了。

java中使用redis----jedis

1、导入jar包,我们使用jedis的包。maven的在pom中加入jedis的依赖。并在spring配置文件中添加相关配置。

<!-- redis 单机版 -->
	<bean id="jedis" class="redis.clients.jedis.JedisPool">
		<constructor-arg name="host" value="127.0.0.1"/>
		<constructor-arg name="port" value="6379"/>
	</bean>	
	<!-- redis 集群 -->
	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
		<constructor-arg name="nodes">
			<set>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="6380"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="6381"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="6382"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="6383"></constructor-arg>
				</bean>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="6384"></constructor-arg>
				</bean>
				
			</set>
		</constructor-arg>
	</bean>

配置完后,写一个redisHandel接口

public interface RedisHandel {
	
	
	String get(String key);
	String set(String key, String value);
	Long del(String key);
	Long hSet(String hKey, String key, String value);
	String hGet(String hKey, String key);
	Long hDel(String hKey, String key);
	Long incr(String key);
	Long expire(String key, int seconds);
	Long persist(String key);
}

写两个类分别实现redisHandel接口,一个单机版,一个集群版(篇幅问题,不大量拷贝代码)

注:jedisCluster用完之后不要close,一旦close那么集群就关闭了。

@Component(value="redisHandelCluster")
public class RedisHandelCluster implements RedisHandel {

	@Autowired
	private JedisCluster jedisCluster; 
	
	public String get(String key) {
		String result = jedisCluster.get(key);
		return result;
	}
}
@Component(value="resisHandelSingle")
public class ResisHandelSingle implements RedisHandel {

	@Autowired
	private JedisPool jedisPool; 
	
	public String get(String key) {
		Jedis jedis = jedisPool.getResource();
		String result = jedis.get(key);
		jedis.close();
		return result;
	}
}

写测试类,注入任一想测试的。我测试的是集群。便注入集群工具类 redisHandelCluster。

调用里面的set方法向集群中添加一条数据,然后在集群中查看该数据有没有添加进去。

最后:

在使用redis的时候,在service层。

一、先去redis中查询,如果没有再去数据库。从数据库中查询出来后向redis中放一份。

二、可以再服务启动后,先放一部分数据到redis中,查询的时候做第一步的操作。

今天跟朋友讨论了以下大量数据的情况下如何将高频检索项放入redis中。

我的想法是,可以先查,然后放到redis中,并给其添加过期时间。当下一次再命中该条记录的时候,将其过期时间延长。以此类推,非高频检索项会随着时间的推移被redis清除。留下来的当然几乎全是高频命中的记录。

当然也可以项目启动后放一部分认为是将来可能高频命中的记录,并添加过期时间。再按过期排除。

关于保留热点数据其实redis给我们了一些更方便的操作:

redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值