NoSql,key-value,数据在内存中,二进制序列化数据,
redis和memcached是key-value的Nosql,主要用来做缓存的。
列存储主要用HBase,用作大数据。
见文档
见文档
见文档
中央缓存:经常要被查询的热点数据,把数据库的热点数据同步到Redis 内存,减轻数据库压力,减少访问时间。
计数器应用:支持自增,注册用户数,浏览次数,转发数、点赞数等等。
实时防攻击系统:暴力破解:使用工具不间断尝试各种密码进行登录。防:ip—>num,到达10次以后自动锁定IP,30分钟后解锁
设定有效期的应用:vip,红包,当session使用,存储登录对象, 设定一个数据,到一定的时间失效。 自动解锁,购物券
自动去重应用:set
构建队列系统:使用 list 可以构建队列系统,使用 sorted set 甚至可以构建有优先级的队列系统。秒杀:可以把名额放到内存队列(redis),内存就能处理高并发访问。
消息订阅系统:Pub/Sub 构建实时消息系统 Redis 的 Pub/Sub 系统可以构建实时的消息系统,比如很多用 Pub/Sub 构建的实时聊天系统的例子,比如QQ群消息。
排行榜:zset有排序功能,可以实现各种排行榜
Redis 的官方下载站是 http://redis.io/download,可以去上面下载最新的安装程序下来。http://redis.cn/
带上配置启动redis服务
在redis解压目录cmd,redis-server.exe redis.windows.conf。(带上配置,不然会使用原始默认配置) (然后注意不要关闭服务端)
连接到redis进行操作
方式一:redis-cli -h 127.0.0.1 -p 6379
方式二:D:\soft\Redis-x64-5.0.9>redis-cli.exe
方式三:直接双击redis-cli.exe
127.0.0.1:6379> set name mingfeng //将字符串值value关联到key
OK
127.0.0.1:6379> get name //返回key关联的字符串值
"mingfeng"
127.0.0.1:6379> keys * //获取所有key列表
1) "name"
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> expire name 10 //设置key的过期时间(xx秒后过期)
(integer) 1
127.0.0.1:6379> ttl name //查看key的过期时间
(integer) -2
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> clear //清除记录
127.0.0.1:6379> mset name mf age 31 sex nan //批量设置一个或多个 key-value 对
OK
127.0.0.1:6379> keys *
1) "sex"
2) "name"
3) "age"
127.0.0.1:6379> mget name age sex //返回所有(一个或多个)给定 key 的值
1) "mf"
2) "31"
3) "nan"
127.0.0.1:6379> incr age //将 key 中储存的数字值增1(key不存在,则初始化为0,再加1)
(integer) 32
127.0.0.1:6379> incr age
(integer) 33
127.0.0.1:6379> get age
"33"
127.0.0.1:6379> decr age //将 key 中储存的数字值减1(key不存在,则初始化为0,再减1)
(integer) 32
127.0.0.1:6379> get age
"32"
127.0.0.1:6379> incrby age 5 //自增多少
(integer) 37
127.0.0.1:6379> decrby age 8
(integer) 29
接上
127.0.0.1:6379> del age //删除key
(integer) 1
127.0.0.1:6379> keys *
1) "sex"
2) "name"
127.0.0.1:6379> expire sex 1
(integer) 1
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1 //换库,有16个库,默认在0号库,0号库无标识,其他库有标识
OK
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> mset name mf sge 20
OK
127.0.0.1:6379[1]> keys *
1) "sge"
2) "name"
127.0.0.1:6379[1]> flushdb //清空当前库
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> mset name mf age 20
OK
127.0.0.1:6379[1]> keys *
1) "age"
2) "name"
127.0.0.1:6379[1]> flushall //清空所有库
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> lpush stus zs ls //将一个或多个值 value 插入到列表 key 的表头(最左边)
(integer) 2
127.0.0.1:6379> lrange stus 0 1 //返回列表 key 中指定区间内的元素,0-1
1) "ls"
2) "zs"
127.0.0.1:6379> lrange stus 0 -1 //返回列表 key 中指定区间内的元素,查询所有的stop为-1即可
1) "ls"
2) "zs"
127.0.0.1:6379> lrange stus 1 -1 //返回列表 key 中指定区间内的元素,1-所有
1) "zs"
127.0.0.1:6379> rpush stus ww zl wbd //将一个或多个值 value 插入到列表 key 的表尾(最右边)
(integer) 5
127.0.0.1:6379> lrange stus 0 -1
1) "ls"
2) "zs"
3) "ww"
4) "zl"
5) "wbd"
127.0.0.1:6379> lpop stus //移除并返回列表 key 的头(最左边)元素
"ls"
127.0.0.1:6379> lrange stus 0 -1
1) "zs"
2) "ww"
3) "zl"
4) "wbd"
127.0.0.1:6379> rpop stus //移除并返回列表 key 的尾(最右边)元素
"wbd"
127.0.0.1:6379> lrange stus 0 -1
1) "zs"
2) "ww"
3) "zl"
127.0.0.1:6379> lpush stus aa bb cc dd ee aa bb ff gg
(integer) 12
127.0.0.1:6379> lrange stus 0 -1
1) "gg"
2) "ff"
3) "bb"
4) "aa"
5) "ee"
6) "dd"
7) "cc"
8) "bb"
9) "aa"
10) "zs"
11) "ww"
12) "zl"
127.0.0.1:6379> lrem stus 2 aa //根据count值移除列表key中与参数 value 相等的元素
(integer) 2 //count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素
127.0.0.1:6379> lrange stus 0 -1
1) "gg"
2) "ff"
3) "bb"
4) "ee"
5) "dd"
6) "cc"
7) "bb"
8) "zs"
9) "ww"
10) "zl"
127.0.0.1:6379> lrem stus -1 bb //count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素
(integer) 1
127.0.0.1:6379> lrange stus 0 -1
1) "gg"
2) "ff"
3) "bb"
4) "ee"
5) "dd"
6) "cc"
7) "zs"
8) "ww"
9) "zl"
通过lpush和rpop,或rpush和lpop可实现队列
通过lpush和lpop,或rpush和rpop可实现栈
可见chm文档
java客户端包括:Redisson,aredis,JDBC-Redis,Jedis,JRedis,等
1.创建普通java项目
2.创建lib包, 导两个jar包, add as library
3.写代码测试
public class JedisTestString {
@Test
public void test(){
//获取链接
Jedis jedis = new Jedis("127.0.0.1",6379,2*1000);
//简单操作
jedis.set("name","mf");
System.out.println(jedis.get("name"));
//关闭连接
jedis.close();
}
}
public class JedisTestPoolSpring {
@Test
public void test(){
//连接池配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(2); //最小连接
config.setMaxTotal(8); //最大连接
config.setMaxWaitMillis(2*1000); //连接超时时间
config.setTestOnBorrow(true); //在获取之前校验连接是否可用
//1 创建连接池
//2 配置连接池的参数
JedisPool pool = new JedisPool(config,"127.0.0.1",6379,2*1000);
//3 通过连接池获取连接
Jedis jedis = pool.getResource();
//4 操作
jedis.set("name","mingfeng");
System.out.println(jedis.get("name"));
//5 释放连接
jedis.close();
//6 销毁连接池
pool.destroy();
}
}
要自己写,不推荐
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* 整个单例: 枚举限制实例只有一个就是单例
*/
public enum JedisUtil {
INSTANCE;
private static JedisPool pool = null;
static {
//1 创建连接池配置对象
JedisPoolConfig config = new JedisPoolConfig();
//2 对连接池配置对象进行配置
config.setMaxIdle(2);//最小连接数
config.setMaxTotal(10);//最大连接数
config.setMaxWaitMillis(2*1000);//超时时间
config.setTestOnBorrow(true);//测试连接是否畅通时机
//3 通过配置对象创建连接池对象 //正常来说应该配置到properties
pool = new JedisPool(config,"127.0.0.1",6379,2*1000);
} //没加密码参数
//4 获取连接
/*public Jedis getResource(){
return pool.getResource();
}*/
public Jedis getCollection(){
if(pool!=null){
return pool.getResource();
}
return null;
}
//6 释放连接
public void release(Jedis jedis){
if (jedis != null) {
jedis.close();
}
}
//常用操作封装到里面
//设置字符串
public void set(String key,String val){
Jedis jedis = null;
try {
jedis = this.getCollection();
jedis.set(key,val);
} catch (Exception e) {
e.printStackTrace();
}finally {
this.release(jedis);
}
}
//获取字符串
public String get(String key){
Jedis jedis = null;
try {
jedis = this.getCollection();
return jedis.get(key);
} catch (Exception e) {
e.printStackTrace();
}finally {
this.release(jedis);
}
return null;
}
//设置带添加超时时间的字符串
public void set(String key,String val,int seconds){
Jedis jedis = null;
try {
jedis = this.getCollection();
//设置值时设置超时时间
jedis.setex(key,seconds,val);
} catch (Exception e) {
e.printStackTrace();
}finally {
this.release(jedis);
}
}
}
public class JedisTestJedisUtil {
public static void main(String[] args) {
Jedis jedis = JedisUtil.INSTANCE.getCollection();
jedis.set("name","lisisi" );
System.out.println(jedis.get("name"));
}
}
Spring data:spring对数据操作的支持规范,我们的数据是多种类型,rdbms(msyql),redis(Nosql),es,mq
Spring data redis :spring操作redis
Spring data jpa :操作关系型数据库
。。。
Springboot Spring data redis:简化spirngdata对redis的配置
1.搭建spirngboot项目
A 创建maven项目
B 导包 parent web test
C 启动类
2.使用springdataredis
A 导包
B 配置属性
C 编写测试类 (基于springboot的测试类)
D 使用springdataredis 提供的工具类 直接操作redis
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
# redis 属性信息
## redis数据库索引(默认为0)
spring.redis.database=0
## redis服务器地址
spring.redis.host=localhost
## redis服务器连接端口
spring.redis.port=6379
## redis服务器连接密码(默认为空)
spring.redis.password=
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
## 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=2
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1ms
## 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class SpringDataTest {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate redisTemplate; //可以存对象,对象要实现序列化才能向redis存储
@Test
public void testString(){
stringRedisTemplate.opsForValue().set("name", "mingfeng");
System.out.println(stringRedisTemplate.opsForValue().get("name"));
}
@Test
public void testObject(){
redisTemplate.opsForValue().set("laozhu",new User(1L,"老朱"));
System.out.println(redisTemplate.opsForValue().get("laozhu"));
}
}
从内存到磁盘,通过配置实现
配置文件redis.windows.conf:
bind 127.0.0.1 指定那些ip可以访问我
port 6379 默认端口,可以改
timeout 0 超时时间,0:默认永不超时
loglevel notice 日志级别,notice相当于info
logfile "" 日志输出位置,如:logfile "./redis.log"
save 900 1 redis持久化的第一个策略,rdb策略,将数据存储到磁盘并生成.rdb后缀的文件
save 300 10
save 60 10000 如果一分钟写了10000次就往rdb文件写一次,写数据并打乱进行编码
appendonly no 生成.aof文件,写一次追加一把,时间不满足rdb的范围就往.aof写,满足后从.aof刷到.adb
掉电重启后会先校验appendonly是否为yes,如果是会拿到.aof里面内容解析,再加上rdb里面内容放到内存
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照,默认开启该模式.
如何关闭 rdb 模式:save “”
# save 900 1 //至少在900秒的时间段内至少有一次改变存储同步一次
# save xxx
# save 60 10000
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集,默认关闭该模式。
如何开启aof模式:
appendonly yes
小结:
redis是怎么保存数据?
redis为了考虑效率,保存数据在内存中.并且考虑数据安全性,还做数据持久化,如果满足保存策略,就会把内存的数据保存到数据rdb文件,还来不及保存那部分数据存放到aof更新日志中。在加载时,把两个数据做一个并集。
淘汰一些数据,达到redis数据都是有效的,节约内存资源。选择合适的淘汰策略进行淘汰。
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
allkeys-lru:从所有数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
maxmemory //自己设置大小
maxmemory-policy volatile-lru //配置淘汰策略