Redis——数据结构
String(字符串):String是简单的 key-value 键值对,一般json都是序列化成String存入redis中的
List(列表):一个链表或者说是一个队列,每个列表支持超过40亿个元素。
Hash(字典):利用key拿出hashMap,当hashMap少时是一个一维数组
Set(集合): 集合成员是唯一的
Sorted Set(有序集合):每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序
tempalate区别
boundXXXOps:直接连接一个key,一个指令一次性操作;
opsForXXX:获取一个operator,没有指定操作的对象(key),可以在一个连接(事务)内操作多个key以及对应的value;
SortQueryBuilder
SortQuery<String> query = SortQueryBuilder
.sort("hanlist")// 排序的key
//.by("pattern") key的正则过滤
.noSort() //不使用正则过滤key
.get("2") //在value里过滤正则,可以连续写多个get
.limit(0, 5) //分页,和mysql一样
.order(SortParameters.Order.DESC) //正序or倒序
.alphabetical(true) //ALPHA修饰符用于对字符串进行排序,false的话只针对数字排序
.build();
redisTemplate.sort(query);
链表操作
redisTemplate.boundListOps("namelist").leftPush("张飞");//指定列表的key,左边压入
redisTemplate.boundListOps("namelist").rightPush("张飞");//指定列表的key,右边压入
redisTemplate.boundListOps("namelist").remove(1, "关羽");//指定列表的key,删除指定索引
List list = redisTemplate.boundListOps("namelist2").range(0, 10);//获取一个范围内的所有元素
tring s = (String) redisTemplate.boundListOps("namelist1").index(1);//获取指定索引的元素
redis 127.0.0.1:6379> LPUSH runoobkey redis(integer) 1
redis 127.0.0.1:6379> LPUSH runoobkey mongodb(integer) 2
redis 127.0.0.1:6379> LPUSH runoobkey mysql(integer) 3
redis 127.0.0.1:6379> LRANGE runoobkey 0 10
哈希操作
redisTemplate.boundHashOps("namehash").put("a", "唐僧");//大key,小key,put进元素
redisTemplate.boundHashOps("namehash").delete("user1","user2","user3");//大key中,批量删除指定的小key
redisTemplate.boundHashOps("namehash").get("b");
List values= redisTemplate.boundHashOps("namehash").values();//获取所有value
Set keys = redisTemplate.boundHashOps("namehash").keys();//获取使用键
127.0.0.1:6379> HMSET runoobkey name "redis tutorial"
127.0.0.1:6379> HGETALL runoobkey
Set集合操作
Redis的Set是string类型的无序集合。,这就意味着集合中不能出现重复的数据。
Redis 中 集合是通过哈希表实现的
redisTemplate.boundSetOps("nameset").add("曹操");
redisTemplate.boundSetOps("nameset").remove("孙权");
redisTemplate.delete("nameset");
Set members = redisTemplate.boundSetOps("nameset").members();
redis 127.0.0.1:6379> SADD runoobkey redis (integer) 1
redis 127.0.0.1:6379> SADD runoobkey mongodb (integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql (integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql (integer) 0
redis 127.0.0.1:6379> SMEMBERS runoobkey
Sorted Set(有序集合)
redis 127.0.0.1:6379> ZADD runoobkey 1 redis(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 2 mongodb(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql(integer) 0
redis 127.0.0.1:6379> ZADD runoobkey 4 mysql(integer) 0
redis 127.0.0.1:6379> ZRANGE runoobkey 0 10 WITHSCORES
Redis——持久化配置(X)
Redis-RDB
【文件属性】
dbfilename dump.rdb #dbfilename:文件名
dir ./#相对于的目录位置
【IO策略】
save 900 1 ## 速率:900秒后,1个ke
save 300 10 ## 速率:300秒后,10个key
save 60 10000 ## 速率:60秒后,如果更改了10000个key,则每60个一次io操作
stop-writes-on-bgsave-error yes ##出现磁盘爆棚时,阻塞客户端“变更操作”
rdbcompression yes ##是否压缩,压缩则可以减少传输,但增加cpu消耗
Redis-AOF
Aof重写过程:
建立子进程读取日志文件 利用Aof缓冲区整合客户端指令+原有aof指令
IO化新的文件,然后新旧替换
Ps:BGREWRITEAOF可以手动重写;
【文件属性】
appendonly yes ##开启AOF
appendfilename appendonly.aof ##指定名称 默认在运行目录下生成aof我们要指定哦
【save策略】
appendfsync everysec
## always:即改即写
## everysec:每秒存;
## no:缓冲区决定!关闭启动
【rewrite策略】-舍弃不必要的日志,避免aof过大
no-appendfsync-on-rewrite no ##【异步重写】在rewrite期间,暂缓文件同步,防止IO中断的恢复
auto-aof-rewrite-min-size 64mb ##【最小触发尺寸,默认“64mb”,建议“512mb” 】
auto-aof-rewrite-percentage 100 ##【增张比例触发尺寸,默认“64mb”,建议“512mb” 】
Redis——回收配置(X)
maxmemory-policy
noeviction:返回错误当内存限制达到
allkeys-lru:尝试回收最少使用的键,使得新添加的数据有空间存放
volatile-lru:尝试回收最少使用的键,过去集合的键
allkeys-random:随机回收
volatile-random:随机回收获取的
volatile-ttl:优先回收存活时间较短的、
Redis——日志配置
(1)进入文件:vim redis.conf
(2)修改输出位置:logfile ""
(3)修改输出等级:loglevel notice
1. debug:会打印出很多信息,适用于开发和测试阶段
2. verbose(冗长的):包含很多不太有用的信息,但比debug要清爽一些
3. notice:适用于生产模式
4. warning : 警告信息
Redis——Lua
Lua数据类型
Lua声明变量:
local a,b = 1,2
local a = {1,2,3}
Lua操作符号
/**
* @逻辑操作符
*/
print(1 and 5) -- 5
print(1 or 5) -- 1
print(not 0) -- false
print('' or 1) -- ''
/**
* @连接操作符 ..
*/
print('hello'..''..'world') -- hello world
Lua分支语句
if 条件表达式 then
语句块
elseif 条件表达式 then
语句块
else
语句块
end
Lua循环语句
for i=1 ,100 do
sum = sum+1
end
Lua表数据结构
people = {name = 'zhouy',age = 29 }
people['name'] = 'value'
for index,value in ipairs(people) do
print(index)
print(value)
end
Lua函数声明
local function square (num)
return num*num
end
Lua举例使用
local current = redis.call('GET', KEYS[1])
if current == ARGV[1]
then redis.call('SET', KEYS[1], ARGV[2])
redis.call('expire',KEYS[1],30000);//设置过期时间
return true
end
return false
Lua——SpringBoot操作
/*
将lua加载成bean
*/
@Bean
public DefaultRedisScript<Boolean> redisScript() {
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/checkandset.lua")));
redisScript.setResultType(Boolean.class);
return redisScript;
}
/*
将bean的lua丢到redisTemplate.execute中执行
execute(RedisScript<T> script, List<K> keys, Object... args);
*/
@Autowired
DefaultRedisScript<Boolean> redisScript;
@RequestMapping(value = "testredislua", method = {RequestMethod.GET})
@ResponseBody
public Object testredislua() {
redisTemplate.execute(redisScript, Collections.singletonList("testredislua"), "hahaha", "3333");
return redisTemplate.opsForValue().get("testredislua");
}
Redis——原生事务指令
/**
* 【开启、执行事务】
*/
redisTemplate.multi();
/**
* 【监听,需要try,catch一下让事务回滚】
*/
redisTemplate.watch("username");//监听
redisTemplate.unwatch();//取消监听
/**
* 【redis操作】………………
*/
/**
* 【执行缓存好的命令】
*/
redisTemplate.exec();
/**
* 【回滚并取消事务】
* 回滚之前这个线程执行过的redis指令
*/
redisTemplate.discard();
Redis——分布式锁
原生指令:
setnx key val:当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
expire key timeout:为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
delete key:删除key
getset key:先 get 旧值,后set 新值,并返回 key 的旧值(old value),具有原子性。当 key 存在但不是字符串类型时,返回一个错误;当key 不存在的时候,返回nil ,在Java里就是 null。
Java封装: