Interview topics sprint --Redis

Redis topics

Redis persistence mechanism

RDB ----------> snapshot of a dataset in memory; turned on by default; -------> dump.rdb

配置 : save  60  10  --------> 60s内, 有10个key发生变化, 触发RDB操作.

优点 : 
	1). 恢复速度快 ; -----> 
	2). 占用磁盘空间小
	
缺点 : 		
	1). 容易丢失数据 ; ------> 丢失数据风险高 
	2). 如果内存中的数据量过大 , 会造成持久化时, 造成大量的磁盘IO , 及CPU , 有可能会影响其他的线程; 
	3). 文件不可读

AOF -----------> redis instruction operation, the operation log; default unopened; -----> append only file

开启 : 
	appendonly yes
	
	#appendfsync always
	appendfsync everysec
	#appendfsync no
	

优点 : 
	1). 文件是可读的 ;
	2). 丢失数据的风险小 ;
	
缺点 : 
	1). 恢复速度慢 ;
	2). aof的日志文件可能会比较大 ;
	


日志重写 : 
	
	bgrewriteaof
	


redis 中的数据库一共有16个 , 默认为第一个0 号数据库 ;

切换数据库 : select  0 ; 

Redis out of memory strategies

Overview:

每台redis的服务器的内存都是有限的,而且也不是所有的内存都用来存储信息。

而且redis的实现并没有在内存这块做太多的优化,所以实现者为了防止内存过于饱和,采取了一些措施来管控内存。

Redis memory settings:

maxmemory <bytes> 

Out of memory (replacement) policy:

1). volatile-lru -> remove the key with an expire set using an LRU algorithm
	
	只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据
	
2). allkeys-lru -> remove any key according to the LRU algorithm
	
	优先删除掉最近最不经常使用的key,用以保存新数据
	
3). volatile-random -> remove a random key with an expire set
	
	只从设置失效(expire set)的key中,(随机)选择一些key进行删除,用以保存新数据
	
4). allkeys-random -> remove a random key, any key
	
	随机从all-keys中(随机)选择一些key进行删除,用以保存新数据 
	
5). volatile-ttl -> remove the key with the nearest expire time (minor TTL)
	
	只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据
	
6). noeviction -> don't expire at all, just return an error on write operations
	
	不进行淘汰,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error

配置 : 
	
	maxmemory-policy noeviction

Number of samples :

maxmemory-samples 3

Redis 中的 LRU 不是严格意义上的LRU算法实现,是一种近似的 LRU 实现,主要是为了节约内存占用以及提升性能。Redis 有这样一个配置 —— maxmemory-samples,Redis 的 LRU 是取出配置的数目的key,然后从中选择一个最近最不经常使用的 key 进行置换,默认的 5,可以通过调整样本数量来取得 LRU 置换算法的速度或是精确性方面的优势。

1559557517522
Here Insert Picture Description
Here Insert Picture Description
Cache penetration

Cache penetration, refers to certain data query a database does not exist. Normal use caching process generally, data query to cache queries, if there is no key or key has expired, then query the database, and the query to the object into the cache. If the database query object is empty, the cache is not putting them in.
1559558795953

@Override
public List findByCategoryId(Long categoryId) { // -1 / -10
// 加入缓存的代码:
List list = (List) redisTemplate.boundHashOps(“content”).get(categoryId);

if(list==null){
	System.out.println("查询数据库===================");
	TbContentExample example = new TbContentExample();
	Criteria criteria = example.createCriteria();
	// 有效广告:
	criteria.andStatusEqualTo("1");
	
	criteria.andCategoryIdEqualTo(categoryId);
	// 排序
	example.setOrderByClause("sort_order");
	
	list = contentMapper.selectByExample(example);
	if(list !=null){
		redisTemplate.boundHashOps("content").put(categoryId, list);
    }
}else{
	System.out.println("从缓存中获取====================");
}

return list;

}
Solution:

1) Set the expiration time

@Override
public List findByCategoryId(Long categoryId) {
// 加入缓存的代码:
List list = (List) redisTemplate.boundValueOps(“content_”+categoryId).get();

if(list == null){
	System.out.println("查询数据库===================");
	TbContentExample example = new TbContentExample();
	Criteria criteria = example.createCriteria();
	// 有效广告:
	criteria.andStatusEqualTo("1");
	
	criteria.andCategoryIdEqualTo(categoryId);
	// 排序
	example.setOrderByClause("sort_order");
	
	list = contentMapper.selectByExample(example);
	if(list != null){
		redisTemplate.boundValueOps("content_"+categoryId).set(list); //-1 
    }else{  //-1 , -2 , -10 
        redisTemplate.boundValueOps("content_"+categoryId).set(null); //null
        redisTemplate.expire("content_"+categoryId,7200, TimeUnit.SECONDS);
    }
}else{
	System.out.println("从缓存中获取====================");
}

return list;

}
. 2) only query cache, not querying the database;

image-20200206150953540

Cache breakdown

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞 。

solution :

1). 对热点数据 , 不设置过期时间 ;  

2). 互斥锁

3). 只查询redis缓存 , 不查询数据库 ;

public class RedisDemo {

private static Lock lock = new ReentrantLock();

public static String getData(String key) throws InterruptedException {
    
    String result = getDataFromRedis(key); //从redis获取数据
	
    if(result == null){ // 如果数据为null , 需要从数据库中获取 lock.lock();  lock.unlock(); lock.tryLock()
        
        if(lock.tryLock()){ //尝试获取锁
            
            result = getDataFromMysql(key); //从数据库中查询
            
            if(result != null){ //如果查询到数据, 就缓存在redis中
                saveDataToRedis(key,result);
            }
            lock.unlock();//释放锁
        }else{
            TimeUnit.MILLISECONDS.sleep(100);
            result = getData(key);
        }
    }
    return result;
}

private static void saveDataToRedis(String key, String result) {
    System.out.println("保存数据到redis中 , key - value ");
}

private static String getDataFromMysql(String key) {
    System.out.println("从数据库中获取数据 ");
    return null;
}

public static String getDataFromRedis(String key){
    System.out.println("从redis中获取数据 ");
    return null;
}

}
Cache avalanche

Cache avalanche, refers to a certain point in time, centralized cache expired.

One of the causes of avalanches, as in the time of writing, going to didodecyl zero, will soon usher in a wave of panic buying, this wave of commodity time are concentrated into the cache, the cache assumptions one hour . So that by the time one o'clock in the morning, the cache on these commodities have expired. And for this article can access the query, both fell on the database for the database, it will produce periodic pressure peaks.

solution

1) If the cache expiration time, divided according to the service needs, different types of data, can set different expiration time, not to the same expiration time, causing a cache expires at the same time point;

2) only query redis, not querying the database;

Redis version Linux installation

1) Upload redis-3.0.0.tar.gz

alt + p ------> put D:/redis-3.0.0.tar.gz 

2) Install the C language compiler environment

yum install gcc-c++   (需要联网)

3) extracting archive

tar  -zxvf redis-3.0.0.tar.gz

4) Compile Source

cd  redis-3.0.0

make

5) Install

make  install  PREFIX=/usr/local/redis

6). Redis copy decompression profile directory redis.conf installation directory to redis

cp redis.conf  /usr/local/redis

7) Start

cd  /usr/local/redis

bin/redis-server redis.conf

After the start, the interface is as follows (do not close the window, the default is the foreground):

1563413526684

Published 92 original articles · won praise 3 · Views 2765

Guess you like

Origin blog.csdn.net/weixin_44993313/article/details/104581937