本文主要介绍
1. redis基本介绍(什么是Nosql,什么是分布式缓存)
2. 缓存方案对比(Ehcache、Memache、Redis)
3. Redis各数据类型API介绍(String,Hash,list,set,zset)
1. Redis基本介绍
1. 什么是Nosql?
关系型数据库:MySQL,SQLServer,Oracle
NoSql: not only Sql 可以存数据,做缓存;具有高可用(多节点) 高性能读取
高可用:普通的数据库无法为大数据访问下并发查询 单表极限为 600-700w 400-500w 普通DBA在300w左右的时候,就需要考虑到海量数据,当数据达到一定量时,就不适合做大数据分析了
===>>> NoSql 水平(横向)扩展方便高效 (节点扩容):
高性能读取:平时数据库需要创建表,创建字段,而NoSql是键值对,数据存储简单 增加和删除缓存非常简单高效 (普通数据库达到百万之后,增加和删除会很低效)
传统项目数据访问量小,基本用的是纯数据库,不会使用NoSql;如果一个项目没有使用到任何NoSql数据库,可以理解为是一个非常传统的数据库
常见分类:
- 键值对数据库 Redis, Memcache
- 列存储数据库 Hbase,Cassandra( 这两个都是在大数据领域的)
- 文档型数据库 MongoDB(C++开发的,是基本分布式文件存储的),CouchDB
- 图形数据库 Neo4J,FlockDB
2. 什么是分布式缓存?
- 提升读取速度性能
- 分布式计算领域
- 为数据库降低查询压力
- 跨服务器缓存 (任意节点都能快速访问)
- 内存式缓存
3. 什么是Redis?
- NoSql (不仅仅能存取数据,而且是缓存)
- 分布式缓存中间件
- key-value存储(类似于hashmap形式)
- 提供了海量数据存储访问
- 数据存储在内存中,读取更快
- 非关系型、分布式、开源、水平扩展
2. 缓存方案对比(Ehcache、Memache、Redis)
Ehcache:
优点:是基于java开发的 (整合效果更好)
基于JVM缓存
简单、轻巧、方便
实例:很多开源框架都会使用:MyBatis Hibernate
缺点:
集群不支持
分布式不支持
Memache
优点:
简单的 key-value存储 (只能存储简单的String类型)
内存使用率高
多核处理多线程
缺点:
无法容灾 (数据无法持久化) (宕机数据无法恢复 )
无法持久化
Redis
优点:
丰富的数据结构
持久化
主从同步,故障转移 (需搭建集群)
内存数据库
缺点:
单线程
单核
Memache 与 Redis 对比:
1. Memache不能做持久化,redis可以
2. Memache只能存储简单的String类型,而Redis可以存储丰富的数据
3. Redis各数据类型API介绍(String,Hash,list,set,zset)
常用命令
- keys * 查看所有的key
- keya a* 查看所有a开头的key
- keya *a 查看所有a结尾的key
- type name 查看key为“name”对应的数据的类型
- select 1 切换到库 2
- flushdb 清除当前库DB所有数据
- flushall 清除所有数据库(DB)数据
1. String
get/set/del 查询/设置/删除
- get age 查看key为age对应的值
- set name kay 设置key为"name"值为"kay" (set age 18) 存在key时,直接覆盖原来的值
- setnx age 10 设置age为10 (当已经存在age这个key时,不覆盖 这个API返回请求影响的行数 如果已存在key,则返回0)
- getrange name 0 -1 (name= kay123) 返回 kay123
- getrange name 2 4 返回y12
- setrange name 1 000 将 name 对应的值的 下标为1开始的内容替换成 000 kay123 ===>>> k00023
- del name 删除key为name
查看/设置过期时间
- ttl age 查看key为age的过期时间 (-1 为无穷大,不过期 ; -2 过期 此时调用get age 会返回nil) time to leave
- expire age 30 设置key为age的过期时间为30秒
字符串相关操作
append key 合并字符串
- append name 123 将key为"name" 的值拼接上123 执行之前kay 执行之后:kay123
- strlen key 字符串长度
- strlen name 获取key为“name”值的长度
加减操作
- incr/decr num 累加/减
- incr age 对key为age的值进行累加 操作之前 10 操作之后 11(每次加1)
- decr age 累减 (与inctr age相对应)
- incrby/decrby key num 累加/减 给定数值
- incrby age 10 对key为“age”的值进行 +10 操作之前 age=19 操作之后age=29
- decrby age 10 与incrby age 10 相对应
批量设置/取值
- mset / mget 统一的多个设值或者取值
- mset k1 aa k2 bb 设置key为k1值为aa key为k2值为bb
- mget k1 k2 获取 k1 k2的值
- msetnx k1 aaa k3 bbbb (因为k1已经存在,所有不会重新生成也不会修改k1的值,k3也不会生成)
- msetnx key1 value1 key2 value 只有当key1 key2都不存在时,才会设置成功
2. Hash
类似于Map存储结构化的数据。比如存储一个对象(不能有嵌套的对象)
user{
name:kay
age:10
}
获取/设置 属性对应的值
hset key property value
- hset user name kay 设置user的name属性为"kay"
- hget user name 获取key为user的name属性对应的值 ===》》类似 user.getName()
对象中多属性获取/设置
- hmset user name kay123 age 10 设置user的name属性为kay123 age属性为10
- hmget user name age 同时获取user 中的name及age属性值
获取所有属性键值对/数量/key/值
- hgetall user 获取user中所有的键值对
- hlen user 获取user对象中的属性数量
- hkeys user 获取user对象中所有属性的key
- hvals user 获取user对象中所有属性的值
属性加减
- hincrby user age 10 为user的属性age增加10
判断属性是否存在
- hexists user age 判断uer中是否存在age属性 (存在返回1 不存在返回0)
删除
- hdel user name 删除user中的name属性
3. list
查看list
lrange list start end 获取数据
- lrange list1 0 -1 查看list1 中从0 到最后的数据
- llen list1 list1的长度 返回3
- lindex list1 0 返回list1中第0位的值 ddd ccc bbb ===》》》 bbb
- lindex list2 0 返回list2中第0位的值 aaa bbb ccc ddd eee ===》》》 aaa
list对象新增/左右放值
- lpush list1 aaa bbb ccc ddd eee 新增一个list1 包含 aaa bbb ccc ddd eee
- rpush list2 aaa bbb ccc ddd eee 新增一个list1 包含 aaa bbb ccc ddd eee
通过 lrange list1 0 -1 和 lrange list2 0 -1
返回的结果分别是
eee ddd ccc bbb aaa
aaa bbb ccc ddd eee
lpush从左边一个个放,而 rpush是从右边一个个放
取出list中值
- lpop list1 从list1的左边取掉一个值 返回 eee 剩余 ddd ccc bbb aaa
- rpop list1 从list1的右边取掉一个值 返回 aaa 剩余 ddd ccc bbb
值替换
- lset list1 0 dddd__ 将list1中第0为的值替换成 dddd__ ddd ccc bbb ====>>> dddd__ ccc bbb
- linsert list1 before ccc aaa 在list1中ccc前插入 aaa dddd__ ccc bbb ===>>>> dddd__ aaa ccc bbb
- linsert list1 after ccc aaa 在list1中ccc后插入 aaa dddd__ aaa ccc bbb ===>>>> dddd__ aaa ccc aaa bbb
删除相同的数据
- lrem list1 2 aaa 删除list1中两个222 dddd__ aaa ccc aaa bbb ===》》》 dddd__ ccc bbb
- lrem list1 1 aaa 删除list1中1个222 dddd__ aaa ccc aaa bbb ===》》》 dddd__ ccc aaa bbb
截取
- lrange list1 1 -1 dddd__ ccc aaa bbb ===>>> ccc aaa bbb
4. set
增/查/删
- sadd set1 aaa bbb ccc ddd ddd aaa bbb 添加set1包含aaa bbb ccc ddd ddd aaa bbb (会自动去重)
- smembers set1 查询 set1 中的内容 =====》》》》 ccc ddd aaa bbb
- scard set1 查看set1中数量
- sismember set1 aaa 查看set1中是否包含aaa (返回结果中 1 包含 0不包含)
- srem set1 aaa 删除set1中的aaa ccc ddd aaa bbb =====》》》》ccc ddd bbb
- spop set 移除一个
- srandmember set3 3 从set3中随机获取3个值
- smove set4 set3 10 将set4中的10移到set3中
差集/交集/并集
差集:
- sdiff set4 set3 set4中有set3中没有
- sdiff set3 set4 set3中有set4中没有
交集
- sinter set4 set3
并集
- sunion set4 set3
5.zset
zset == sorted set 排序的set可以去重可以排序 (比如可以根据用户积分做排名,积分作为set的一个数值,根据数值可以在排序。set中的每一个member都带有一个分数)
增/查/删
zadd zzset1 10 value1 11 value2 12 value3 9 value4 新增/增加(已存在zset1将只设值)
- zadd zset1 10 aa 11 bb 12 cc 9 dd
- zrange zset1 0 -1 查找zset1中所有的内容====>>> dd aa bb cc
- zrange zset1 0 -1 withscores 查找zset1中所有的内容及其对应的分数 ====>>> dd 9 aa 10 bb 11 cc 12
此时再次调用
zadd zset1 25 abc 35def
zrange zset1 0 -1 withscores ====>>> dd 9 aa 10 bb 11 cc 12 abc 25 def 35
- zrem zset1 dd aa 删除zset1中的 dd aa
zrangk zset1 value 获取zset1中value对应的下标
- zrank zset1 abc 查看在zset1中abc的下标
获取对应的分数
- zscore zset1 abc 查看zset1中abc对应的分数
统计个数
- zcard zset1 查看zset1中有多少项
zcount zset1 分数1 分数2 统计两个分数间个数
- zcount zset1 20 50 统计zset1中,分数在20分到50分之间(20<= XX <= 50)的项数 返回数字
- zrangebyscore zset1 20 50 withscores 列出分数在20分到50分之间(20<= XX <= 50)的项 加了withscores则列出对应的分数
- zrangebyscore zset1 (20 (50 withscores 列出分数在20分到50分之间(20< XX < 50)的项 加了withscores则列出对应的分数
******* (需要在数字之前,在数字之后,会报错 ERR min or max is not a float)
分页查找
- zrangebyscore zset1 20 50 limit 1 2 分页,在zrangebyscore zset1 20 50的结果集中,查看下标为1 ,查找2项
Redis官方API文档 http://redisdoc.com/index.html