Rumah  >  Artikel  >  pangkalan data  >  Apakah penyelesaian bagi Java untuk mengendalikan redis dan menetapkan tamat tempoh pada awal pagi keesokan harinya?

Apakah penyelesaian bagi Java untuk mengendalikan redis dan menetapkan tamat tempoh pada awal pagi keesokan harinya?

WBOY
WBOYke hadapan
2023-05-26 15:40:591290semak imbas

Tetapan redis operasi Java tamat tempoh pada awal pagi keesokan harinya

Senario

Apabila menanyakan data, saya menghadapi masalah bahawa data perlu ditetapkan untuk tamat tempoh dalam redis seterusnya hari, tetapi redis mempunyai Tiada API yang sepadan, jadi saya perlu menyelesaikannya sendiri

Idea

Kira perbezaan masa antara awal pagi hari berikutnya dan masa semasa, dan tetapkan perbezaan masa sebagai masa tamat redis, kita boleh mencapai Kesan yang diingini

kod

/**
     * 计算第二天凌晨与当前时间的时间差秒数
     * @param
     * @return java.lang.Long
     * @author shy
     * @date 2021/3/12 18:10
     */
    public static Long getNowToNextDaySeconds() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }

mendapat perbezaan masa, dan selebihnya pada dasarnya tiada masalah.

Dilampirkan ialah kelas alat Redis:

/**
 * 操作redis
 * @author shy
 * @date 2020/12/10 10:01
 */
@Service
public class RedisService {
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Autowired
    private RedisTemplate<String, Object> redisTemplate;
	
	/**
	 * 判断String类型key是否存在
	 *
	 * @param key
	 * @return 
	 * @author shy
	 * @date 2018年11月13日 下午1:40:37
	 */
	public boolean hasStringKey(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.opsForValue().getOperations().hasKey(key);
	}
	
	/**
	 * 判断String类型key是否存在
	 *
	 * @param key
	 * @return 
	 * @author shy
	 * @date 2018年11月13日 下午1:43:51
	 */
	public boolean nonStringKey(String key) {
		return !hasStringKey(key);
	}
	/**
	 * 设置String类型key,String类型value,过期时间timeout,TimeUnit
	 *
	 * @param key
	 * @param value
	 * @param timeout
	 * @param timeUnit
	 * @author shy
	 * @date 2018年12月10日13:53:38
	 */
	public void setStringKey(String key, String value, Long timeout, TimeUnit timeUnit) {
		if (StringUtils.isBlank(key) || Objects.isNull(timeout)) {
			throw new EmptyParameterException();
		}
		stringRedisTemplate.opsForValue().set(key, value, timeout, timeUnit);
	}
	
	public void setStringKey(String key, String value) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		stringRedisTemplate.opsForValue().set(key, value);
	}
	/**
	 * 获取String类型value
	 *
	 * @param key
	 * @return
	 * @author shy
	 * @date 2018年11月12日 下午7:09:31
	 */
	public String getStringValue(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.opsForValue().get(key);
	}
	
	/**
	 *	获取Key的过期时间
	 *
	 * @param key
	 * @return
	 * @author shy
	 * @date 2019年4月25日17:28:36
	 */
	public Long getExpire(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.getExpire(key);
	}
	
	/**
	 *	设置Key的过期时间
	 *
	 * @param key
	 * @return
	 * @author shy
	 * @date 2019年4月25日17:28:36
	 */
	public Boolean setExpire(String key,Long timeout, TimeUnit timeUnit) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.expire(key, timeout, timeUnit);
	}	
	
	/**
	 * value自增+n
	 * @param key
	 * @return
	 * @author shy
	 * @date 2019年4月8日15:54:30
	 */
	public Long setIncrementValue(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.opsForValue().increment(key, 1L);
	}
	/**
	 * 设置String类型key,Object类型value,过期时间timeout
	 *
	 * @param key
	 * @param value
	 * @param timeout
	 * @author shy
	 * @date 2018年12月10日13:54:07
	 */
	public void setObjectKey(String key, Object value, Long timeout,TimeUnit time) {
		if (StringUtils.isBlank(key) || Objects.isNull(timeout)) {
			throw new EmptyParameterException();
		}
		redisTemplate.opsForValue().set(key, value, timeout, time);
	}
	
	public void setObjectKey(String key, Object value) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		redisTemplate.opsForValue().set(key, value);
	}
	
	/**
	 * 获取Object类型value
	 *
	 * @param key
	 * @param clazz
	 * @return 
	 * @author shy
	 * @date 2019年11月6日10:01:30
	 */
	@SuppressWarnings("unchecked")
	public <T> T getObjectValue(String key, Class<T> clazz) {
		if (StringUtils.isBlank(key)) {
			return null;
		}
		return (T) redisTemplate.opsForValue().get(key);
	}
	
	/**
	 * 移除单个String类型key
	 *
	 * @param key 
	 * @author shy
	 * @date 2018年11月13日 上午10:42:01
	 */
	public void removeSingleStringKey(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		stringRedisTemplate.opsForValue().getOperations().delete(key);
	}
	
	/**
	 * 移除Collection<String>类型keys
	 *
	 * @param keys 
	 * @author shy
	 * @date 2018年11月13日 下午3:15:16
	 */
	public void removeMultiStringKey(Collection<String> keys) {
		if (CollectionUtils.isNotEmpty(keys)) {
			stringRedisTemplate.opsForValue().getOperations().delete(keys);
		}
	}
	
	/**
	 * redis key 模糊查询
	 * @author shy
	 * @date 2021年1月4日 上午11:21:45
	 * @param key
	 * @return
	 */
	public Set<String> queryStringKeys(String key) {
		 return redisTemplate.keys(key + "*");
	}
}

Pengenalan fungsi dasar tamat tempoh Redis

Apabila kami menggunakan redis, kami biasanya menetapkan masa tamat tempoh, sebanyak tentu ada juga yang tidak menetapkan masa luput iaitu tidak akan luput.

Apabila kami menetapkan masa tamat tempoh, bagaimana redis menentukan sama ada ia telah tamat tempoh dan strategi yang digunakan untuk memadamkannya.

Tetapkan masa tamat tempoh

Apabila kami menetapkan kunci, kami boleh memberikan masa tamat tempoh, contohnya, nyatakan bahawa kunci ini hanya boleh bertahan selama satu jam tetapkan kumpulan kunci untuk bertahan selama satu jam, kemudian bagaimana redis memadamkan kumpulan kunci ini satu jam kemudian?

Jawapannya ialah: pemadaman biasa + pemadaman malas.

Apa yang dipanggil pemadaman biasa bermaksud bahawa secara lalai, redis memilih beberapa kekunci secara rawak dengan masa tamat tempoh ditetapkan setiap 100ms, menyemak sama ada ia telah tamat tempoh dan memadamkannya jika ia tamat tempoh. Melintasi semua kunci dengan masa tamat tempoh setiap 100ms akan menyebabkan penurunan prestasi yang ketara, sila ambil perhatian. Redis sebenarnya akan memilih beberapa kekunci secara rawak untuk menyemak dan memadam setiap 100 milisaat.

Tetapi masalahnya ialah pemadaman biasa boleh menyebabkan banyak kunci yang telah tamat tempoh tidak dipadamkan apabila masanya tamat, jadi anda perlu memadamnya dengan malas, maksudnya, apabila anda mendapat kunci, redis akan menyemak untuk melihat sama ada kunci ini ditetapkan Masa tamat tempoh Jadi adakah ia telah tamat tempoh? Jika ia tamat tempoh, ia akan dipadamkan.

Dengan menggabungkan dua kaedah di atas, ia dijamin bahawa kunci yang telah tamat tempoh akan dimatikan. Semua kunci tamat tempoh tidak akan dipadamkan secara automatik apabila masa tamat tempoh dicapai, jadi penggunaan memori tidak akan berkurangan selepas tamat tempoh.

Tetapi sebenarnya, ini masih menjadi masalah Jika banyak kunci tamat tempoh terlepas oleh pemadaman biasa, dan kemudian ia tidak disemak dalam masa dan pemadaman malas dilakukan, ia akan menyebabkan sejumlah besar tamat tempoh. kunci untuk terkumpul dalam ingatan dan menggunakan memori redis , bagaimana untuk menangani keadaan ini?

Jawapannya ialah: gunakan mekanisme penghapusan ingatan.

Penghapusan Memori

Jika redis mengambil terlalu banyak ingatan, beberapa penyingkiran akan dilakukan pada masa ini. Terdapat beberapa strategi seperti berikut:

  • : Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, ralat akan dilaporkan untuk data yang baru ditulis Senario sebenar ini biasanya tidak digunakan. noeviction

  • : Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, dalam ruang kekunci, keluarkan kunci yang paling kurang digunakan (ini adalah yang paling biasa digunakan) allkeys-lru

  • : Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, kunci dialih keluar secara rawak daripada ruang kunci Ini biasanya kurang digunakan. allkeys-random

  • : Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, dalam ruang kekunci dengan set masa tamat, kunci yang paling kurang digunakan baru-baru ini dialih keluar. volatile-lru

  • : Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, kunci dialih keluar secara rawak daripada ruang kunci dengan masa tamat tempoh ditetapkan. volatile-random

  • : Apabila memori tidak mencukupi untuk menampung data yang baru ditulis, dalam ruang kekunci dengan masa tamat tempoh ditetapkan, kunci dengan masa tamat tempoh lebih awal akan dialih keluar terlebih dahulu. volatile-ttl

Penghapusan memori akan mencetuskan syarat penyingkiran untuk memadam kunci tertentu Ini juga sebab kunci hilang tanpa menetapkan masa tamat tempoh.

Atas ialah kandungan terperinci Apakah penyelesaian bagi Java untuk mengendalikan redis dan menetapkan tamat tempoh pada awal pagi keesokan harinya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam