亮,有一计

文章 分类 评论
52 17 10

站点介绍

这是一个热爱和别人一起交流学习的程序员所建立的个人博客 欢迎大家交流讨论

redis杂谈

liang 2022-11-24 54 0条评论 redis深度学习 redis

首页 / 正文
本站的文章若无特殊标明转载的话均为原创,有些文章在我的csdn个人站也有,两者基本上是同步的 博客地址

发布于2022-07-08

redis过期键的删除策略

三种基础删除策略

  • 立即删除:Redis不可能时时刻刻遍历所有被设置了生存时间的key来检测数据是否已经到达过期时间,然后对它进行删除.立即删除能保证内存中数据最大的新鲜度,因为他实时的释放掉过期key的内存占用,但是立即删除对cpu是最不友好的,因为删除操作会占用cpu的时间,如果正好碰到cpu很忙的时候,会造成额外的压力.会产生大量的性能消耗,并且影响到数据的读取操作.
  • 惰性删除:数据到达过期时间,不做处理.等下次访问该数据时,如果未过期就返回数据,发现已过期就删除,并返回不存在(它是对内存最不友好的,如果过期了但是并没有再次访问了,会有大量的垃圾key残留)
  • 定期删除:每隔一段时间执行一次删除过期键操作,并通过限制删除操作时间和频率来减少删除操作对cpu时间的影响

    • 周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
    • CPU性能占用设置有峰值,检测频度可以自定义设置
    • 内存压力不是很大,长期占用内存的冷数据会被持续清理

redis过期淘汰策略

八种淘汰策略
策略名称含义解释
noeviction不会驱逐任何key(生产的默认配置就是这个)
allkeys-lru对所有的key使用LRU算法进行删除 (基本都是用这个,比较稳定的方案)
volatile-lru对所有设置了过期时间的key使用LRU算法进行删除
allkeys-random对所有key随机删除
volatile-random对所有设置了过期时间的key随机删除
volatile-ttl删除马上要过期的key
allkeys-lfu对所有key使用LFU算法进行删除
volatile-lfu对所有设置了过期时间的key使用LFU算法进行删除

微信抢红包案例

思路分析

首先肯定是用Redis,redis天生单线程高可用,可以无锁实现加锁的代码效果,其次红包数值存储应该用list数据结构(set不允许重复,但是红包金额能够重复),并且list的pop出栈操作自动是原子性的不需要加锁,其次需要存储用户的抢红包记录
可以用hash结构.最后如果这些需要持久化的话可以最后开启异步线程同步到MySQL或者消息队列.

代码案例

import cn.hutool.core.util.IdUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

@RestController
public class RedPackageController {

    public static final String RED_PACKAGE_KEY = "redpackage";

    public static final String RED_PACKAGE_CONSUME_KEY = "redpackage:consume";

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping("/sendRedPackage")
    public String sendRedPackage(int totalMoney, int redPackageNumber) {
        //拆分红包
        Integer[] splitRedPackages = splitRedPackage(totalMoney, redPackageNumber);
        String key = RED_PACKAGE_KEY + IdUtil.simpleUUID();
        //不需要加锁,一个人发,也不需要原子性,所以可以分成两部分设置
        redisTemplate.opsForList().leftPushAll(key, splitRedPackages);
        redisTemplate.expire(key, 1, TimeUnit.SECONDS);
        return "success";
    }

    @PostMapping("/robRedPackage")
    public String robRedPackage(String redPackageKey, String userId) {
        Object redPackage = redisTemplate.opsForHash().get(RED_PACKAGE_CONSUME_KEY + redPackageKey, userId);
        if (redPackage != null) {
            throw new RuntimeException("你已经抢过红包了,不允许重复抢");
        }
        Integer money = (Integer) redisTemplate.opsForList().leftPop(RED_PACKAGE_KEY + redPackageKey);
        if (money == null) {
            throw new RuntimeException("红包已经被抢完了");
        }
        redisTemplate.opsForHash().put(RED_PACKAGE_CONSUME_KEY + redPackageKey, userId, money);
        //后续如果需要进行持久化存储可以开启异步线程进入MySQL或者进入MQ消息队列再进一步处理
        return "success";
    }

    private Integer[] splitRedPackage(int totalMoney, int redPackageNumber) {
        int useMoney = 0;
        Integer[] redPackageNumbers = new Integer[redPackageNumber];
        ThreadLocalRandom random = ThreadLocalRandom.current();
        for (int i = 0; i < redPackageNumber; i++) {
            if (i == redPackageNumber - 1) {
                redPackageNumbers[i] = totalMoney - useMoney;
            } else {
                //二倍均值法进行计算,这样的值比较平均(忽略小数)
                int avgMoney = ((totalMoney - useMoney) / (redPackageNumber - i)) * 2;
                redPackageNumbers[i] = 1 + random.nextInt(avgMoney - 1);
            }
            useMoney = useMoney + redPackageNumbers[i];
        }
        return redPackageNumbers;
    }


}

短链接案例

思路分析

用新浪微博的短链接算法来生成对应的短链接地址字符串,然后存入redis的hash结构当中

import java.security.MessageDigest;

public class ShortUrlUtil {

    // 可以自定义生成 MD5 加密字符传前的混合 KEY
    private static final String key = "test";

    // 要使用生成 URL 的字符
    private static final String[] chars = new String[]{"a", "b", "c", "d", "e", "f", "g", "h",
            "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
            "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
            "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z"

    };

    public static String[] shortUrl(String url) {
        // 对传入网址进行 MD5 加密
        String hex = md5ByHex(key + url);
        String[] resUrl = new String[4];
        for (int i = 0; i < 4; i++) {
            // 把加密字符按照8个字节一组分为4段
            String sTempSubString = hex.substring(i * 8, i * 8 + 8);
            // 将他看为16进制串与 0x3FFFFFFF(30位1)进行位与运算,超过30位的忽略处理
            // 这里需要使用 long 型来转换,因为 Integer.parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用long ,则会越界
            long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
            StringBuilder outChars = new StringBuilder();
            for (int j = 0; j < 6; j++) {
                // 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引
                long index = 0x0000003D & lHexLong;
                // 把取得的字符相加
                outChars.append(chars[(int) index]);
                // 每次循环按位右移 5 位
                lHexLong = lHexLong >> 5;
            }
            // 把字符串存入对应索引的输出数组
            resUrl[i] = outChars.toString();
        }
        return resUrl;
    }

    /**
     * MD5加密(32位大写)
     */
    public static String md5ByHex(String src) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = src.getBytes();
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            StringBuilder hs = new StringBuilder();
            String stamp;
            for (byte value : hash) {
                stamp = Integer.toHexString(value & 0xFF);
                if (stamp.length() == 1)
                    hs.append("0").append(stamp);
                else {
                    hs.append(stamp);
                }
            }
            return hs.toString().toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }

}

代码示例

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;

@RestController
public class ShortUrlController {

    public static final String SHORT_URL_KEY = "short:url";

    @Resource
    private HttpServletResponse response;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping(value = "/shortUrl/encode")
    public String shortUrlEnCode(String longUrl) {
        String[] keys = ShortUrlUtil.shortUrl(longUrl);
        int i = ThreadLocalRandom.current().nextInt(4);
        String shortUrlKey = keys[i];
        redisTemplate.opsForHash().put(SHORT_URL_KEY, shortUrlKey, longUrl);
        return "http://1270.0.1:5555/" + shortUrlKey;
    }

    @PostMapping("/shortUrl/decode")
    public void shortUrlDecode(String shortUrlKey) throws IOException {
        String longUrl = (String) redisTemplate.opsForHash().get(SHORT_URL_KEY, shortUrlKey);
        response.sendRedirect(longUrl);
    }


}

评论(0)

最新评论

  • manchester united tøj

    Araofclmh australia vm barn Drakt KaseyTls Kristieif real madrid drakt ThadHilly RhysHorns liverpool tröja barn DedraNett AlissaGal Maglia Chile Mondiali 2022 MilanFait OnitaSass chelsea drakt AlannahEa NaomiLev liverpool tröja barn JuanTregu AdrieneBe Brasilien VM 2022 Landsholdstrøje MilfordNe SimonJsh maglie napoli 2022 JuliaLayt EzraPouli marseille tröja LinoldDi JannieSpr chelsea matchtröja GlendaMes CraigTasm Atalanta Drakt LenaBella LashondaB Maglia Armenia Mondiali 2022 JermaineE RicoLeona danmark VM tröja Shananwsw Gildaohft VM fotbollstrojör VM CaryBrans TrenavcZ Portugal VM 2022 Landsholdstrøje JewelJano Jacquetta Island VM 2022 Landsholdstrøje FreyaYdyr TobiasHer Portugal VM 2022 Landsholdstrøje AzucenaVe BeatriceV australia VM 2022 Drakt VeronaTul MoseButtr Maglia Wales Mondiali 2022 StacyHytt TobiasHer Portugal VM 2022 Landsholdstrøje AzucenaVe

  • Hello Word !

    我发现我的评论功能,加载不了头像!朋友圈和相册也加载不了,音乐播放器也不显示,求解!

  • il: Clark11370

    Margenemh 357 fotballdrakter til bedriftslag Coreyc – Coin Media – журнал о заработке в интернете Francesco CasieDalu maglia argentina AbbieLand JessRoman Website Darrellie PaulinaRu Profile of ChristieRy SidneyMgw ToneyKrog Liverpool Tøj - Blog Profile - iotaJots JaimieChe TriciaBri Wolearn: GregoryEmelia: Magliette Calcio Poco Prezzo SheltonTh WayneHone 438 Chile Tröja Barn Leopol – Profile – Primescool Forum CharlineC VitoHartf norge bortedrakt to receive adulation, always insists the result is most important and will therefore be thoroughly disheartened by this display. As is often the case in friendly matches, there was a lack FedericoW صفحه اصلی – Maglia Porto KurtBrise of urgency for large periods during this match, though Wales did link play promisingly in attack through Wilson and Brooks. Italy will be among the nations in pot one for the Euro 2020 qualifying draw in Dublin on 2 December having drawn 0-0 against Portugal in their previous match to ensure a second-place finish in Nations League Group 3A. TanjaFitz Elizabeth manchester city tröjor KenPoulin CarenWhar Maglia Juventus Bambino EmeliaBow Stephaine liverpool drakt DarlaFulm FerneSuvg barcelona FC drakt Meaganold EmilyEise arsenal drakt KourtneyS Kellyejoh inter trøje JamaalWor Loisniyet psg drakt MaricelaS CecileSwa lavora come produttore esecutivo della serie CharissaC ChastityF Home - Liverpool Drakt EmilGmvut CasieDalu maglia argentina AbbieLand UrsulaLof rashford numero maglia KareemCap SSNGilber arsenal drakt 2022 MelodeePe

  • arsenal trøjer

    BrittnyFo atletico madrid tröja ClaritaBu ZJRBridge magliette psg JosephDur Valentina real madrid drakt MarionTol NevaLangt manchester united drakt BraydenBo RodolfoCa Real Madrid Tröja KelliefjL BettinaMi Notenbrood op top niveau MillardMh RichardMo arsenal drakt Bradleyjo TanyaNuge Spanien landsholdstrøje AprilBuck JoannaShe Billige Polen Fotballdrakter NiklasWes Maryellen terza maglia milan PrincessN AnhGiffen real madrid tröja FredricAu JoannaShe Billige Polen Fotballdrakter NiklasWes EssieOate juventus matchtröja PreciousF EdnaTippe sabinahogan447 EffieOcon MichaelaH liverpool tröja barn KayleighM JonnieHoc nuova maglia roma 2021/22 CortezSha YDZClaire ac milan drakt KathleneH CedricBac manchester united drakt Peterysjl HaicoQcmw Maglia Brasile Femmina ThereseJu DoreenMes napoli trøje JadaLanni

  • maglie hellas verona 2022

    Your style is very unique in comparison to other folks I have read stuff from. Many thanks for posting when you have the opportunity, Guess I'll just bookmark this blog. maglie hellas verona 2022 IlanaGxrn frankrike tröja JaneenZtt

日历

2023年02月

   1234
567891011
12131415161718
19202122232425
262728    

友情链接

文章目录

推荐关键字:

站点公告
本站的文章若无特殊标明转载的话均为原创,有些文章在我的csdn个人站也有,两者基本上是同步的 博客地址
点击小铃铛关闭