Redis高級
事務(wù)
redis事務(wù)本質(zhì):一組命令的集合项乒,一個事務(wù)的所有命令都會被序列化,在事務(wù)執(zhí)行的過程中葵蒂,會按照順序執(zhí)行
一次性交播、順序性、排他性
redis的事務(wù)沒有隔離級別的概念
所有的命令在事務(wù)中践付,并沒有直接被執(zhí)行秦士,只有發(fā)起執(zhí)行命令才會被執(zhí)行
redis單條命令是保存原子性的,但是事務(wù)不保證原子性
redis的事務(wù)執(zhí)行:
開啟事務(wù)(multi)
命令入隊
執(zhí)行事務(wù)(exec)
放棄事務(wù)的命令為:discard
事務(wù)異常:
1永高、編譯型異常(代碼有問題隧土,命令有錯):事務(wù)中所有的命令都不會被執(zhí)行
2、運行時異常:如果事務(wù)隊列存在語法性乏梁,那么執(zhí)行命令的時候次洼,其他命令可以正常執(zhí)行关贵,錯誤命令拋出異常
監(jiān)控
悲觀鎖
- 悲觀遇骑,認為什么時候都會出問題,無論做什么都會加鎖
樂觀鎖
- 樂觀揖曾,認為什么時候都不會出現(xiàn)問題落萎,所以不會加鎖亥啦。更新數(shù)據(jù)的時候去判斷,在此期間是否有人修改這個數(shù)據(jù)
- 獲取version
- 更新的時候比較version
監(jiān)視對象使用 watch [key] 解鎖使用 unwatch
#shell1
127.0.0.1:6379> set money 200
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money #監(jiān)視money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec #執(zhí)行失敗
(nil)
#shell2
127.0.0.1:6379> get money
"200"
127.0.0.1:6379> set money 1000 #另外一個線程修改了元素
OK
Jedis
public class JedisTest {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
System.out.println(jedis.ping());
}
}
SpringBoot使用redis
SpringBoot2.x之后练链,把jedis換成了lettuce
jedis:采用的直連翔脱,多個線程操作,不安全媒鼓,如果想要避免不安全届吁,需要使用jedis pool連接池(bio)
lettuce:采用netty,實例可以在多個線程內(nèi)共享绿鸣,不存在線程不安全的情況(nio)
spring:
redis:
host: 127.0.0.1
database: 0
port: 6379
@Autowired
private RedisTemplate redisTemplate;//操作不同的數(shù)據(jù)類型
@Test
void contextLoads() {
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();
redisTemplate.opsForValue().set("k1","v1");
System.out.println(redisTemplate.opsForValue().get("k1"));
}
@Test
void redisTest() throws JsonProcessingException {
User user = new User("張三", 2);
//String jsonUser = new ObjectMapper().writeValueAsString(user);
redisTemplate.opsForValue().set("user",user);
System.out.println(redisTemplate.opsForValue().get("user"));
}
配置序列化配置類
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate (RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//配置jackson序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//配置String序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//使key和hashkey使用String序列化
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
//使value和hashvalue使用json序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
redis.conf配置
1疚沐、單位 redis中對大小寫不敏感
2、可以包含其他配置文件
3潮模、網(wǎng)絡(luò)
#綁定ip
bind 127.0.0.1
#保護模式
protected-mode yes
#端口設(shè)置
port 6379
4亮蛔、通用配置
#以守護進程的方式運行,默認為no
daemonize yes
#如果以后臺方式運行擎厢,需要指定一個pid文件
/var/run/redis_6379.pid
#日志
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably) 生產(chǎn)環(huán)境
# warning (only very important / critical messages are logged)
loglevel notice
#日志的輸出位置及文件名
logfile
#數(shù)據(jù)庫數(shù)量 默認16個
database 16
#是否總是顯示logo
always-show-logo yes
5究流、快照
持久化,在規(guī)定的時間內(nèi)动遭,執(zhí)行了多少次操作芬探,則會持久化到 .rdb .aof
redis是內(nèi)存數(shù)據(jù)庫,沒有持久化厘惦,數(shù)據(jù)斷電即失
# 如果900s內(nèi) 至少有 1 key進行了修改灯节,就進行持久化操作
save 900 1
# 如果300s內(nèi) 至少有 10 key進行了修改,就進行持久化操作
save 300 10
# 如果60s內(nèi) 至少有 10000 key進行了修改绵估,就進行持久化操作
save 60 10000
# 之后的持久化會自定義測試
# 持久化出現(xiàn)錯誤是否繼續(xù)工作
stop-writes-on-bgsave-error yes
# 是否壓縮rdb文件
rdbcompression yes
# 保存rdb文件時進行錯誤檢查
rdbchecksum yes
# rdb文件保存的目錄
dir ./
6炎疆、安全
# 設(shè)置密碼
config set requirepass 123456
# 登錄
auth 123456
# 設(shè)置能連接上redis的客戶端的最大數(shù)量
maxclients 10000
# redis設(shè)置最大的內(nèi)存
maxmemory <byte>
# 內(nèi)存達到上限的處理策略
# noeviction: 不刪除策略, 達到最大內(nèi)存限制時, 如果需要更多內(nèi)存, 直接返回錯誤信息。(默認值)
# allkeys-lru: 所有key通用; 優(yōu)先刪除最近最少使用(less recently used ,LRU) 的 key国裳。
# volatile-lru: 只限于設(shè)置了 expire 的部分; 優(yōu)先刪除最近最少使用(less recently used ,LRU) 的 key形入。
# allkeys-random: 所有key通用; 隨機刪除一部分 key。
# volatile-random: 只限于設(shè)置了 expire 的部分; 隨機刪除一部分 key缝左。
# volatile-ttl: 只限于設(shè)置了 expire 的部分; 優(yōu)先刪除剩余時間(time to live,TTL) 短的key亿遂。
maxmemory-policy noeviction
7、AOF設(shè)置
# 默認不開啟aof模式渺杉,默認使用rdb方式持久化蛇数,在大部分情況下rdb基本夠用
appendonly no
# 持久化文件名字
appendfilename "appendonly.aof"
#每次修改都會 sync。消耗性能
appendfsync always
#每秒執(zhí)行一次 sync是越,可能會丟失這一秒的數(shù)據(jù)耳舅。
appendfsync everysec
#不執(zhí)行 sync,這個時候操作系統(tǒng)自己同步數(shù)據(jù)倚评,速度最快
appendfsync no