redis基础入门

1. redis安装
#安装基本的环境
yum install -y gcc-c++
make
make install

#默认的安装路径
/usr/local/bin/

redis 默认不是后台启动的,需要修改配置文件

daemonize yes 表示后台启动

 

2. 启动
redis-server ./redis.conf  #指定配置文件启动服务

#客户端连接服务
redis-cli -p 6379

 

3. 关闭
shutdown
exit

 

4. redis-benchmark
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000  #测试100个并发10万个请求

 

5. redis基础
# 切换数据库
select 3
# 查看大小
dbsize
# 清空当前数据库
flushdb
# 请空所有的数据库
flushall

exists key
move key 1     #移除当前数据库的key, 1:表示当前数据库
expire key 10  #表示10秒钟之后过期
ttl key  #可以查看剩余的时间
type key #查看存储数据的类型

 

6. 面试题

redis 是很快的,官方表示: redis是基于内存操作的,cup不是redis的性能瓶颈,redis的性能瓶颈是机器的内存和网络的带宽,既然可以用单线程实现,就可以用单线程了!所以就使用单线程了

 

redid 是单线程的,为什么还这么快?

首先,多线程不一定比单线程的快。cpu > 内存 > 硬盘

redis 将所有的数据放到内存中的,所以单线程的就是会比较快,如果是多线程的话,就会有cpu的切换,而cpu的切换是比较耗时的,对于内存系统来说,如果没有上下文切换,效率就是最高的,多次读写操作都是在一个CPU上,在内存情况下,这个就是最佳的方案

 

7. redis数据类型
7.1 string 类型命令
#动态修改redis存的字符串,如果key不存在,相当于set key
append key "hello"

# 获取redis字符串的长度
strlen key

incre key #自增

decre key #自减

increby key 10
decreby key 10
getrange key 0 3   #获取指定位置的字符串
getrange key 0 -1  #相当于 get key
setrange key 2 xx  #替换指定位置开始的字符串

setex key 30 "hello"  #设置过期时间
setnx key "redis"     #如果数据不存在,设置key的值,如果数据存在不覆盖key的值

mset key1 v1 key2 v2 key3 v3  #批量设置值
mget key1 key2 key3

msetnx key1 v1 key2 v2 key3 v3  #只要有一个设置不成功,就会返回失败。原子性

#存储对象数据
mset user:1:name "zhangsan" user:1:age 25  
mget user:1:name user:1:age

getset key value  #先获取key再设置key的值,并返回之前的值(如果不存在返回nil)

 

7.2 list 类型的命令(栈/队列)
lpush list 1  # 从左边(头部)向列表中塞值
rpush list 2  # 从右边(尾部)向列表中塞值

lpop list # 移除列表的第一个值
lrange list 0 -1  # 获取列表的所有的值

lindex list 0 # 通过下标获取列表的值 (从左边开始)
rindex list 1 # 通过下标获取列表的值 (从右边开始)

llen list # 返回列表的长度

lrem list 1 value # 移除一个指定的值
lrem list 2 value # 移除两个指定的值

ltrim list 1 3  # 将列表的数据进行截取(截取开始的位置和截取结束的位置),list的值会改变成截取之后的值
rpoplpush list1 list2 # 移除列表的最后一个元素,并将这个元素push到一个新的列表中
linsert list before "hello" "other" #向列表的某一个元素的前面插入一个元素(其实是一个链表的结构)
lset list 0 "hello" # 设置list的下标为0的值 (前提是这个list且下标为0的这个数必须是先存在的,不然会设置失败,这是一个更新的操作)

 

7.3 set 集合命令
sadd myset "hello"
members myset #查看set集合的数据
sismember myset "hello" #判断是否存在某个元素
scard myset  #获取集合中元素的个数
srem myset hello #移除set中的某一个元素
srandmember myset #获取集合中随机的一个元素
srandmember myset 2 #获取集合中随机的两个元素
spop myset #随机弹出(移除)集合中的一个元素
smove myset1 myset2 "hello" #将一个指定的元素从一个集合中移动到另外一个集合中

sdiff myset1 myset2  #以myset1作为参照物,myset2中没有的元素,即两个集合的差集
sinter myset1 myset2 #两个几个的交集
sunion myset1 myset2 #两个集合的并集

 

7.4 hash 命令
数据结构想成map就行
hset myhash field1 value1 # 设置值
hset myhash field2 value2
hmset myhash field1 value1 field2 value2 #批量设置值
hgetall myhash  #获取集合中所有的值
hdel myhash field1 #删除hash集合中的某一个元素
hlen myhash #长度
hexists myhash field #判断hash中的某一个元素是否存在
hkeys myhash  #只获取hash中的所有的key
hvals myhash  #只获取hash中的所有的value

hset myhash field3 5
hincre myhash field3 1 #自动加1
hdecre myhash field3 #自动减1

hsetnx myhash field4 value4


hmset user:1 name zhangsan age 12
#适合存储对象的应用场景

 

7.5 zset 有序集合
zadd myset 1 one 2 two 3 three  #添加数据的同时加一个序号进行排序
zrange myset 0 -1  # 获取集合中的所有的数据


zadd salary 2500 zhangsan 3000 lisi 500 wangwu

zrangebyscore salary -inf +inf #-inf表示负无穷, +inf表示正无穷 按照从小到大的顺序进行排序
zrevrange salary 0 -1  # 按照从大到小排序

zrangebyscore salary -inf +inf withscore #查询的数据包括score
zcard salary # 获取集合中的数量
zcount myset 1 3  

 

7.6 geospatial 地理位置
geoadd china:city 29.9 12.90 shanghai
geopos china:city shanghai  #获取指定城市的经度和维度
geodist china:city beijing shanghai km  #两个城市的直线的距离
georadius china:city 110 50 100 km # 以某个点为中心,半径为指定值画圆的附近位置

georadius china:city 110 50 100 km withdist [withcoord] [count 1]
georadiusmember china:city beijing 1000 km  #以北京为中心,找周围1000km以内的城市

 

7.7 Hyperloglog
PFadd mykey a b c d e
PFcount mykey # 统计数量
PFmerger targetkey mykey1 mykey2
PFcount targetkey

 

7.8 Bitmap 位存储

统计用户信息,活跃不活跃,登录未登录、打卡等两个状态的都可以用Bitmaps

Bitmap 位图 都是操纵二进制位进行记录,就只有0和1两种状态

setbit sign 0 1
setbit sign 1 1
setbit sign 2 0
setbit sign 3 1
setbit sign 4 1
setbit sign 5 0

getbit sign 3
bitcount sign

 

8. 事务

redis 单条命令是保证原子性的,但是redis事务是不保证原子性的

redis事务本质是一组命令的集合,一个事务中所有的命令都会被序列化,在事务执行的过程中会按照顺序执行

一次性、顺序性、排他性

不存在原子性

不存在隔离性,所有的命令在事务中并没有被执行,只有在发起执行命令的时候才会真正的被执行

开启事务(multi)
入队
执行事务(exec)

discard # 取消事务

编译时异常

命令错误导致编译失败,执行事务的时候也不会成功,所有的命令都不会执行

运行时异常

不保证事务的一致性

 

9. 锁

悲观锁

无论做什么都会加锁

 

乐观锁

#redis 可以当乐观锁使用

set money 100
watch money  # 监测 money
multi # 开启事务
decreby money 20
increby out 20
exec  # 执行事务

如果一个线程执行上面的命令,在exec之前,有另外一个线程将money的值进行了修改操作,此时这个事务将会执行失败

解决方案
unwatch money #解锁
watch money #获取新的锁
multi
decreby money 20
increby out 20
exec

乐观锁的原理:在执行exec命令之前获取之前的数据的值,判断这个值和之前监视的值是否一致,如果一致才会执行,如果不一致就会执行失败

 

10. jredis

使用Java操作redis

config get requirepass          #获取redis设置的密码
config set requirepass 123456   #设置redis密码
auth 123456  #密码验证
save  #保存修改后的配置文件

 

11. 持久化

RDB触发的规则

1. save规则满足的情况下,会触发RDB规则(dump.rdb)
2. flushall的情况下,也会触发RDB规则
3. 退出redis的时候也会产生rdb文件

 

12. spring boot 整合redis

spring boot 操作数据: spring-data

spring data 和 spring boot 齐名的项目

说明: spring boot 2.x以后原来的jedis被替换成lettuce

jedis 采用的是直连,多个线程操作是不安全的 ,如果想避免不安全,采用jedis pool 连接池 BIO

lettuce 底层是netty ,实例可以在多个线程中共享,不存在线程安全问题 NIO

posted @ 2018-03-27 18:27  紫川先生  阅读(120)  评论(0编辑  收藏  举报