Redis学习笔记(一)

Redis

端口号:6379

默认16个库

单线程 + 多路IO复用

基本数据类型

String

  1. 二进制安全

  2. 最基本的数据类型

原子操作:不会被线程调度机制打断的操作

java中的i++是否是原子操作? 不是

取值 ++ 赋值

i = 0; 两个线程都对i进行 i++ 100次值是多少?

最大值200,最小值2

msetnx 原子性,有一个失败全部失败

底层数据结构:预分配冗余

扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M

字符串最大长度512M

List

单键多值

简单的字符串列表,按照插入顺序排序

底层实际是个双向链表,对两端操作性能很高,通过索引下标的操作中间的节点性能较差

值在键在,值光键亡

操作

lpush

lpop

rpush

rpop

lrange

lindex

linsert key before/after value newvalue

lrem 移除

lset

底层结构 quicklist

元素较少的情况下会使用一块连续内存存储 ,叫做ziplist压缩列表

数据量比较多的时候才会改成quicklist

多个ziplist使用双向指针连起来

redis 将链表和ziplist结合起来组成quicklist

set

sadd key value1 value2 将一个或多个元素加入到集合key中,已存在的member元素将被忽略

smembers key :取出该集合的所有值

sismember key value

scard key :返回该集合的元素个数

srem key value1 value2 ..: 删除集合的某个元素

spop key:随机从该集合中吐出一个值

srandmember key n:随机从集合取出n个值

sinter key1 key2:交集

sunion key1 key2:并集

sdiff key1 key2 : 差集,key1中特有的,k2没有的元素

数据结构

dict字典,字典是用哈希表实现的

hash

键值对集合

string 类型的field和value的映射表

value 是 field - value 类型

第一种

user:{id = 1,name = zhangsan, age = 20}

第二种

user:id 1

user:name zhangsan

user:age 20

第三种

user: id 1

name zhangsan

age 20

第三种即为hash

操作

hset

hget

hmset

hexists

hkeys

hvals

数据结构

两种:ziplist,hashtable

长度较短且个数较少时使用ziplist

否则使用hashtable

有序集合zset

和set相似

没有重复元素的字符串合集

有序集合的每个成员都关联了一个评分score,这个评分被用来按照最低分到对高分的方式排序集合中的成员。集合的成员时唯一的,但是评分可以是重复的

zadd key score1 value1 score2 value2..

zrange key start stop (withscores)

zrangebyscore

zrevrangebyscore

zincrby

zrem

zcount

zrank

数据结构

非常特别的数据结构

hash,hash的作用是关联元素value和权重score,保障value的唯一性,可以通过元素value找到相应的score值

跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表

跳跃表:

有序集合底层可以用数组,平衡树,链表等。

数组不便于元素的插入,删除;

平衡树和红黑树虽然效率高,但结构复杂;

链表需要遍历,效率低;

跳跃表效率堪比红黑树,实现远比红黑树简单

有序链表 --> 跳跃表

跳跃表:分层的链表

配置

网络相关配置

默认情况 bind = 127.0.0.1 只能接受本机的访问请求

不写的情况下,无限制接受任何ip地址的访问

protecd-mod 保护模式,改成no

tcp-backlog = 未完成三次握手队列 + 已完成握手队列

timeout

tcp-keepalive 检测心跳

通用配置

daemonize 后台启动

loglevel 日志级别

debug verbose notice warning

database 16

安全配置

密码

限制配置 LIMITS

maxclients

maxmemory

maxmemory-samples

redis的发布和订阅

一种消息通信模式

发布者 和 订阅者

客户端可以订阅任意频道

SUBSCRIBE

publish

redis新数据类型

bitmaps

专门进行位操作的字符串

本身是字符串

setbit key offset value

可以用来做访问的记录

很多应用的id以一个指定数字开头,直接将用户id和偏移量对应,会造成浪费

通常的做法是每次做setbit的时,将用户id减去这个指定数字。

第一次初始化bitmap时,假如偏移量非常大,那么整个过程执行会比较慢,可能会造成redis 阻塞

getbit key offset

bitcount 统计为1的数量

bitop and

bitop or

HyperLogLog

基数问题:集合中不重复元素个数

MySQL:distinct + count

redis:hash、set、bitmaps

计算精确

占用空间

计算基数所需的空间总是固定的、并且时很小的,降低了一定的精度

每个HyperLogLog键只需要花费12KB内存,就可以计算近2^64个不同元素的基数。

但是因为HyperLogLog只会根据输入计算基数,而不会储存输入元素本身,所以HyperLogLog不能像集合那样,返回输入的各个元素。

pfadd

pfcount

pfmerge:合并两个

Geospatial

经纬度,地理信息

geoadd key 经度 纬度 地点

geopos key 地点

geodist key 地点1 地点2 单位 :两个位置的直线距离

单位 m/km/ft/mi

georadius key 经度 纬度 半径 单位

Jedis操作Redis

  1. 导包 jedis

  2. 创建jedis对象 Jedis jedis = new Jedis(host, port);

  3. 测试

    String value = jedis.ping();

    sout(value);

    注意:redis配置文件:注释bind 关闭保护模式 系统:关闭防火墙

操作key

  1. jedis.keys("*");

  2. jedis.set(key,value);

  3. jedis.mset();

  4. ...

实例:手机验证码

  1. 生成随机6位数字验证密码 --> Random

  2. 2分钟内有效 -->把验证码放到redis里面,设置过期时间120s

  3. 判断验证码是否有效 --> 从redis获取验证码和输入的验证码比较

  4. 每个手机号每天只能输入3次 --> incr 每次发送之后 +1,大于2,不能发送

​伪代码:

//获取六位验证码
public static String  getCode() {
    Random random = new Random();
    String code = "";
    for(int i = 0; i < 6; i++) {
        int rand = random.nextIn(10);
        code += rand;
    }
    return code;
}

//每个手机只能发送3次
public static void verifyCode(String phone, String code){
    Jedis jedis = new Jedis(host,port);
    String countKey = "VerifyCode" + phone + ":count";
    String codeKey = "VerifyCode" + phone + ":code"; 
    String countKey = jedis.get(countKey);
    if(count == null) {
        //如果为空,说明没有发送过验证码
        //设置发送次数是1
        jedis.setex(countKey,24*60*60,1); //发送次数设置为1,设置过期时间一天
    } else if {
        jedis.incr(countKey);//次数加1
    } else {
        sout("超过三次");
        jedis.close();
        return; //后面代码不能执行了,return 后后面代码不执行
    }
    
    String vcode = getCode(); //getCode()生成随机验证码
    jedis.setex(codeKey,120,vcode); //放到redis里面,设置120秒的过期
    jedis.close();
    
}
//验证码校验
public static getReidsCode(String phone, String code) {
    Jedis jedis = new Jedis(host,post);
    String codeKey = "VerifyCode"+phone+":count";
    String redisCode = jedis.get(codeKey);
    
    if(redisCode.equals(code)){
        sout("成功");
    } else {
        sout("失败");
    }
    jedis.close();
}
psvm {
    //模拟验证码发送
    verifyCode();
    //
    getRedisCode();
}

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值