Redis

Redis相对于memcached的优势

1.memcached所有的值都是简单的字符串,redis支持更多丰富的数据类型

2.redis的速度比memcached快很多

3.redis可以持久化其数据

Redis的数据淘汰策略

为了保证redis中的数据都是热点数据,redis内存数据集大小上升到一定大小的时候,就会实施数据淘汰策略。

1.noeviction:当内存限制达到返回错误,并且客户端尝试执行会让更多内存被使用的命令。

2.allkeys-lru:尝试回收最少使用的键(LRU),使得新添加的数据有空间存放

3.volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间

4.allkeys-random:回收随机的键使得新添加的数据有空间存放。

5.volatile-random:回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键

6.volatile-ttl:回收再过期集合的键并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间

Redis为什么需要把数据放到内存中

Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征,如果不将数据放在内存中,磁盘I/O速度会严重影响redis的性能。

Redis适合的场景

会话缓存(sessioncache)

维护一个不是严格要求一致性的缓存,例如用户的购物车信息

全页缓存(FPC)

重启Redis实例后,因为有磁盘对的持久化,用户也不会看到页面加载速度的下降

队列

Redis在内存存储引擎领域的一大优点是提供list和set操作,这使得Redis能作为一个很好的消息队列平台来使用

排行榜/计数器

Redis的set和Sorted Set 使得我们在之心这些操作的时候变得很简单

发布/订阅

非关系型数据库特点

1.数据模型简单

2.需要灵活性更强的it系统

3.对数据库性能要求较高

4.不需要高度的数据一致性

5.对于给定key,比较容易映射复杂的环境

Redis简介

是以key-value形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求(非关系型的、分布式的、开源的。水平可扩展的)
优点:对数据高并发读写
对海量数据的高效率存储和访问
对数据的可扩展性和高可用性
缺点: redis (ACID处理非常简单)
无法做到太复杂的关系数据库模型
Redis是以key-value store存储,data |structure service数据结构服务器。键可以包含: (string)字符串, 哈希,(ist)链表, (set)集合,(zset)有序集合。这些数据集合都支持push/pop、add/remove及取交集和并集以及更丰富的操作,redis支持各种不同的方式排序,为了保证效率,数据都是缓存在内存中,它也可以周期性的把更新的数据写入磁盘或者把修改操作写入追加到文件记。

数据类型String

redis-共分 为五种基本数据类型: String、 Hash、List、 Set、 ZSet
String类型是包含很多种类型的特殊类型,并且是二进制安全的。比如序列化的对象进行存储,比如一张图片进行二进制存储,比如一一个简单的字符串,数值等等。最大容量是512M

set和get方法:设置值: set name bhz取值get name ( 说明设置name多次会覆盖)
删除值: del name
使用setnx (not exist) :name如果不存在进行设置,存在就不需要进行设置了,返回0
使用setex (expired) : setex color 10 red设置color的有效期为10秒,10秒后返回nil ( 在redis里nil表
示空)
使用setrange替换字符串:
set email 174754613@qq.com
setrange email 10 ww (10表示从第几位开始替换, 后面跟上替换的字符串174754613@ww.com)

使用一次性设置多个和获取多个值的mset. mget方法:
mset key1 bhz key2 baikey3 28;对应的mget key1 key2 key3方法
对应的也有msetnx和mgetnx方法。
一次性设置和取值的getset方法:
set key4 CC==getset key4 changchun返回旧值并设置新值的方法
incr和decr方法:对某一个值进 行递增和递减
incrby和decrby方法:对某个值进行指定长度的递增和递减
append [name]方法:字符串追加方法
strlen [name]方法:获取字符串的长度

数据类型Hash

Hash类型是String类型的field和value的映射表,或者说-一个String集合。它的特别适合存储对象,相比较而言,将-一个对象类型存储在Hash类型里要比存储在String类型里占用更少的内存空间,并方便存取整个对象。

形如: hset myhash field1 hello (含义是hset是hash集合,myhash是集合名字field1是字段名hello为其值)使用hget myhash field1获取内容,也可以存储多个值hmset可以进行批量存储多个键值对: hmset myhash sex nan addr beijing,也可使用hmget进行批量获取多个键值对。
同样也有hsetnx,和setnx大同小异。
hincrby和hdecrby集合递增和递减。
hexists是否存在key如果存在返回不存在返回0
hlen返回hash集合里的所有的键数值
hdel删除指定hash的field
hkeys返回hash里所有的字段
hvals返回hash的所有value
hgetall返回hash里所有的key和value

数据结构List

List类型是-一个链表结构的集合,其主要功能有push、pop、获取元素等。更详细的说,List类型是-一个双端链表的结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素, list的设计非常简单精巧,即可以做为栈,又可以作为队列。满足绝大多数需求。
lpush方法:从头 部加入元素(栈)先进后出 形如: lpush list1 “hello” lpush list1 “world”
lrange list1 0 -1 (表示从头取到末尾) world hello
rpush方法:从尾部加入元素(队列)先进先出 形如: rpush list2 “beijing” rpush list2 “sxt”
Irange list2 0 -1 bejjing sxt

insert方法:插入元素 形如:linsert list3 before “one” “three” //在元素“one”之前添加“three”

数据类型set zset

set集合是string类型的无序集合,set是通过hashtable实现的,对集合我们可以取交集、并集、差集。
sadd方法:向名称为key的set中添加元素
小结: set集合不允许重复元素smembers查看set集合的元素
srem方法:删除set集 合元素
spop方法:随机返回删除的key
sdff方法:返回俩个集合的不同元素(哪个集合在前面就以哪个集合为标准)
sdiffstore方法:将返回的不同元素存储到另外-一个集合里

smembers set1 smembers set2 sdiffstore

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXPudl7A-1616408715080)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1597744070985.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dkIjNcsJ-1616408715084)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1597744139511.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vMmICxq-1616408715086)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1597744210179.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-no7NMgBF-1616408715089)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1597744995248.png)]

常用命令

keys * :查询redis中所有的数据

keys list * :模糊匹配

expire name 5 :设置某个key的过期时间

ttl name :获取name的存在时间

persist name :取消过期时间(需要再name还没有过期的时候使用)

select 1 :选择下标为1的数据库

move name 2: 把数据那么移动到下标为2的数据库中

rename name name1 :把name改名为name1

echo :打印命令

dbsize :查看数据库的key数量

info :获取(整个)数据库信息

config get 实时传储收到的请求(返回相关的配置信息)

config get * :返回所有配置

fiushdb :清空当前数据库 select 1 flushdb

flushall :清空所有数据库

redis安全性

因为redis速度相当快,所以在一台比较好的服务器下,一个外部用户在一秒内可以进行15w次的密码 尝试,这一位这你需要设定非常强大的密码来防止暴力破解。

redis不太需要设置密码

vim/usr/loacal/redis/etc/redis.conf

requirepass fooobared

requirepas redis :wq

/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

/usr/local/redis/bin/redis-cli 或者 /usr/local/redis/bin/redis-cli -a 密码

auth 密码

netstat -tunpl |grep redis //查看进程号

kill 进程号

redis主从复制实现读写分离主读从写

1.Master可以拥有多个slave(从)

2.多个slave可以连接同一个master外,还可以连接到其他的slave(slave可以继续连接slave)

3.主从复制不会阻塞master,在同步数据时,master可以继续处理client请求

4.提供系统的伸缩性

主从复制的过程

1.slave与master建立连接,发送sync同步命令

2.master会开启一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存

3.后台完成保存后,就将文件发送给slave

4.slave将此文件保存到硬盘上

主从复制配置

1.clone服务器之后修改slave的ip地址

2.修改配置文件:/usr/local/redis/etc/redis.conf

3.slaveof

4.masterauth

5.使用info查看role角色即可知道时主服务或从服务

Redis事务(一般不用)

multi打开事务,这时设置的数据都会放入队列里进行保存,exec执行,把数据一次存储到redis中,使用discard方法取消事务

redis持久化机制

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。

redis持久化的两种方式

1.snapshotting(快照)默认方式,将内存中以快照的方式写入到二进制文件中,默认为dump.rdb,可以通过配置设置自动做快照持久化的方式,我们可以配置redis在n秒内如果超过m个key则修改就自动做快照

可以容忍数据丢失,实时性要求不高

snapshotting设置

save 900 1 #900秒内如果超过1个key被修改则发起快照保存

save 300 10 #300秒内如果超过10个key被修改,则发起快照保存

save 60 10000 #60秒内如果超过10000个key被修改,则发起快照保存

2.append-only file(缩写aof)的方式,类似与oracle日志,由于快照方式是自一定时间间隔做一次,所以可能发生redis意外down的情况就会丢失最后一次快照后的所有修改的数据、aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到命令中,当redis重新启动appendonly.aof。aof不是立即写到硬盘上,可以通过配置文件修改强制写到硬盘中。

aof设置

appendonly yes //启动aof持久化方式有三种修改方式

#appendfaync always //收到写命令就立即写入到磁盘,效率最慢,但是保证完全的持久化

#appendfsync everysec //每秒写入磁盘一次,在性能和持久化方面做了很好的折中

#appendfsync no //完全依赖os,性能最好,持久化没保证8

redis的发布与订阅消息

redis提供了简单的发布订阅功能

使用subscribe[频道]进行订阅监听

使用publish[频道] [发布内容]进行发布消息广播

缓存穿透如何避免

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找。一些恶意的请求会故意查询不存在的key请求量很大, 就会对后端系统造成很大的压力,这就叫缓存穿透.

如何避免

1.对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2.对一定不存在的key进行过滤,可以把所有的肯能存在的key放到一个大的bitmap中,查询时通过该bitmap过滤

缓存雪崩如何避免

当缓存服务器重启或者大量缓存集中在某一个时间段实效,这样在失效的时候,会给后端系统带来很大压力 。导致系统崩溃.

如何避免

1.在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待

2.做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

3.不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀

Rdies的应用

Redis存储用户信息

RedisConfig类

public class RedisConfig{
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory                                        redisConnectionFactory){
        RedisTemplate<String,Object> redisTemplate=new  RedisTemplate<>();
        //key序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //value序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //hash类型 key序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //hash类型 value序列化
        redisTemplate.setHashValueSerializer(
                                new GenericJackson2JsonRedisSerializer());
        //注入连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        returnn redisTemplate;
    }
}

将用户信息存入redis中

String ticket=UUIDUtil.uuid();

redisTemplate.opsForValue().set(“user:”+ticket,user); //前面是String 后面是对象。

CookieUtil.setCookie(request,response,“userTicket”,ticket);

获取redis中的用户信息

User user=(User)redisTeplate.opsForValue().get(“user:”+userTick);

returnn redisTemplate;
}
}


>将用户信息存入redis中
>
>String ticket=UUIDUtil.uuid();
>
>redisTemplate.opsForValue().set("user:"+ticket,user);    //前面是String 后面是对象。
>
>CookieUtil.setCookie(request,response,"userTicket",ticket);
>
>获取redis中的用户信息
>
>User user=(User)redisTeplate.opsForValue().get("user:"+userTick);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值