redis知识总结

Redis的一些概念

 no-sql --not only sql 非关系型

 key-value数据结构--键值对

 基于内存缓存

 可持久化存储--保证数据可靠性

 支持分布式部署,提供良好可扩展性

雪崩/缓存击穿:
海量的数据访问,请求并发,一旦涌入集群.需要高性能的处理过程;缓存的存在对于高并发的意义非常大,如果缓存失效;海量请求访问数据库;造成数据库宕机;重启数据库后,如果缓存没有恢复数据,导致数据库的二次宕机,这种重复数据库宕机,重启,缓存失效,叫做缓存击穿/雪崩;

redis的过期策略及内存淘汰机制
定期删除+惰性删除策略
(1)为何不用定时删除?
用定时器负责监视key过期删除,虽然内存及时释放,但十分消耗cpu资源,在高并发情况下,CPU要将事件应用在处理请求上,而不是删除key,因而不采用。
定期删除+惰性删除策略如何工作?
定期删除:redis默认100ms检查一次,是否有过期的key,过期则删除,需要署名的是redis并不是每隔100ms检查所有key,而是随机抽取进行检查(若每隔100ms,key进行检查,redis岂不会卡死)
+惰性删除策略:redis的定期删除会使很多key没有被删除,惰性删除策略,会在每次获取某个key时,redis会进行检查,若可以设置过期时间,那么是否过期,过期删除

(2)定期删除+惰性删除策略其他问题?
若定期删除没有删除key,也没有请求key,惰性删除没有生效,这样redis缓存会越来越高,那么就采用内存淘汰机制
在redis.conf中有一行配置 # maxmemory-policyvolatitle-lru 内存淘汰策略

Redis的持久化策略:
rdb
fork一个进程,遍历hash table,利用copy on write,把整个db dump保存下来。Save, shutdown, slave 命令会触发这个操作。粒度比较大,如果save, shutdown, slave 之前crash了,则中间的操作没办法恢复。
aof
把写操作指令,持续的写到一个类似日志文件里。(类似于从postgresql等数据库导出sql一样,只记录写操作)粒度较小,crash之后,只有crash之前没有来得及做日志的操作没办法恢复。

CAP理论
C:consistency(一致性) 数据在某个查看的时间点上保持整体一致;
A:avalibility(可用性)
P:partition(分区)-tolenrence to partition(分区容忍度)
在分布式集群中.只可能同时满足CAP理论中的2个条件
linux下
安装: make && make install
启动: redis-server
连接: redis-cli
后台查看进程 ps -ef |grep redis
redis默认支持16个数据库
select 选数据库
基础命令:set name liu
get name
keys * :获取所有key
type name
del name
帮助:help
退出:exit
关闭:shutdown
清空所有数据库:flushall
清空当前数据库:flushdb

redis的存储命令

string类型命令
自增:incr key 当前键值自增。返回递增后的值(不存在自动创建,存在自动+1)
自减:decr key 减少指定整数
自加浮点:incrbyfloat 第一次加可以得到正确结果,浮点数后再加浮点就会出现精度问题。
尾部追加:append key value
获取字符串长度:strlen key 如果键不存在则返回0。注意,如果键值为空串,返回也是0。
同时设置、获取多个键值:mset key value【key value 。。。】 mget key【key 。。】
生存时间:expire key 10(秒)
TTL查看key的剩余时间,当 key 不存在时,返回 -2 。
清除生存时间 :presist key
设置生存时间单位为毫秒:pexpire key milliseconds

hash数据操作:
hset:执行插入操作时HSET命令返回1,当执行更新操作时返回0。hset user username liu
hget:hget user username
hmset:hmset user username liu age 19
hmget获取对象属性:hget user age username
hgetall
hexist:属性是否存在 hexist user username
hdel:删除对象字段
hkeys:hkeys user 只获取字段名
hvals:获取value属性
hlen:获取hash字段

redis中用的最多的是 hash string

redis中的list结构:
每个元素都是String类型的双向链表 最大长度2的32 次方
我们可以通过push,pop操作从链表的头部或者尾部添加删除元素。这使得list既可以用作栈,也可以用作队列。
查看list:lrange mylist 0 -1

lpush:list头部 添加字符串元素 lpush
lrange:lrange 0 -1 遍历
rpush:在key对应list的尾部添加字符串元素
linsert:特定位置前后添加字符串
lset:设置指定元素下标的元素值

lrem:

从key对应list删除count个和value相同的元素,
count>0,从头到尾顺序删除count个。

redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist5 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist5 2 "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) "foo"
2) "hello"

count<0,尾到头顺序删除,
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist6 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist6 -2 "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) "hello"
2) "foo"
count=0删除全部。

ltrim保留指定范围内的数据

0 -1 :都保留
1 -1 :除第一位都保留

lpop :从list头部删除元素,并返回删除元素
rpop :从list尾部删除元素,并返回删除元素
rpoplpush :从第一个list的尾部移除元素并添加到第二list头部最后返回被移除的元素,整个操作时原子的,若第一个list尾空或者不存在返回nil
lindex :返回名称为key的list中index的位置
llen :返回key对应的list的长度

redis的分布式存储应用

单实例单线程的redis进程不足以高效率使用cpu和内存资源。
配置
vim redis.conf

第11行位置,配置内容表示配置当前redis服务占用的最大内存空间
第62行左右,配置内容表示当前的服务允许登录使用的ip地址
第80行左右,表示protected-mode是否开启保护模式,默认开启
第84行左右,配置当前redis服务启动后占用的端口号
第105行左右,表示客户端连接服务器后,如果空闲时间达到设置的值时间秒,则自动断开连接,减少对服务器的资源浪费(单位s秒)
第128行左右,daemonize表示后台守护进程是否开启,yes表示开启
第150行左右,表示当前服务启动后记录pid进程号的文件路径
第203行左右,表示的是当前redis服务启动后的持久化策略
save 900 1 :900秒至少写入1次数据则存盘;
save 300 10:300秒至少写入10次数据则存盘;
save 60 10000:60秒至少写入10000次数据则存盘;保持不变,
多实例启动
redis-server redis.conf
其它配置文件需修改port 、pid文件
登录各服务测试:redis-cli -p 6380
Jedis 客户端
添加依赖

<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-redis</artifactId>
       <version>1.4.5.RELEASE</version>
</dependency>

连接redis

@Test
public void jedisConnection(){
	Jedis jedis =new Jedis("106.42.150.247",6379);
	String name =jedis.set("name", "liu");
	jedis.expire("name", 100);
	System.out.println(name);
}

数据分片连接池
海量数据存储,分别保存
哈希取余法:key值的任何取值区间映射到整数区间,这样我们就可以利用取余算法,永远将key值对应到一个有限的整数区间内;key.hashCode()&Integer.MAX_VALUE)

public void jedisPool(){
		//构造rdis节点的信息
		List<JedisShardInfo>infoList=new ArrayList<JedisShardInfo>();
		JedisShardInfo info1=new JedisShardInfo("10.24.50.254",6381);
		JedisShardInfo info2=new JedisShardInfo("10.24.50.254",6380);
		JedisShardInfo info3=new JedisShardInfo("10.24.50.254",6379);
		infoList.add(info1);
		infoList.add(info2);
		infoList.add(info3);
		//创建jedis池
		JedisPoolConfig poolConfig=new JedisPoolConfig();
		poolConfig.setMaxTotal(200);
		ShardedJedisPool pool=new ShardedJedisPool(poolConfig, infoList);
		//从池中获取jedis
		ShardedJedis jedis=pool.getResource();
		jedis.set("name", "xiao");
		//关闭就不能使用close,需要return
		pool.returnResource(jedis);
		pool.close();
		
	}
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值