内存数据库
基于内存的nosql数据库:Memchched,Redis
常见的内存数据库:
Memchched可以看成是redis的前身,严格来说,memcached不是数据库,只能叫缓存,不支持持久化。
Redis:内存数据库,支持持久化(RDB,AOF)
Oracle TimesTen:内存数据库(使用少)
内存数据库作用:快
Redis 和 memory cache 的区别
区别:
1. 性能:
redis 只能使用单核,而 memory cache 可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)
2. 内存利用率:
如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。
3. 数据持久化和数据同步
如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
4. 具体应用需求
当然,最后还得说到你的具体应用需求。Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。
Memchched
memchched的基本原理架构
在内存中维护了一张巨大的Hash表
memcached是可以搭建集群,是非常轻量级的,是可以在同一个服务上启动多个memcached
安装memcached
1.需要使用gcc编译器,查看是否有gcc,gcc是c语言在Linux上面的编译器
如果没有gcc使用yum安装
yum -y install gcc
查案gcc的版本
gcc --version
2.安装依赖:libevent库
(1)检测是否有libevent
rpm -qa | grep libevent
(2)如果检测有libevent删除这个libevent
rpm -e libevent
(3)安装包上传Linux:课件中下载
(4)解压安装包(源码包)
tar -zxvf ./soft/libevent-2.0.21-stable.tar.gz -C ./
(5)指定一个编译安装的路径
./configure --prefix=/opt/libevent
(6).编译
make (调用c语言编译器,编译成.0的文件)
(7)安装
make install
3.安装memcached
(1)解压安装包
tar -zxvf ./soft/memcached-1.4.25.tar.gz -C ./
(2)指定安装的路径
./configure --prefix=/opt/memcached --with-libevent=/opt/libevent
(3)编译
make
(4)安装
make install
4.启动memcached
./memcached -u root -d -m 128 -p 11211
-d 守护线程(类似于后台启动)
-m 内存的大小
-p 端口号
-u 指定启动的用户,注意如果是由root用户启动时,必须指定
查看是否启动成功
ps -ef | grep memcached
root 9712 1 0 04:44 ? 00:00:00 ./memcached -u root -d -m 128 -p 11211
root 9732 2479 0 04:44 pts/0 00:00:00 grep --color=auto memcached
操作Memcached
命令方式:
使用telnet写入数据
查看是否安装telnet:rpm -qa | grep telnet
安装:yum -y install telnet
使用:telnet 192.168.2.111 11211
[root@bigdata111 bin]# telnet 192.168.2.111 11211
Trying 192.168.2.111...
Connected to 192.168.2.111.
Escape character is '^]'.
add key 0 0 4
abcd
STORED
#add key 0 0 4
#解释:
#add 添加数据的命令
#key 数据的key,自己指定
#0 是一个标志位,不用关心
#0 代表数据过期的时间,如果为0表示不过期
#4 代表数据的长度
get key
VALUE key 0 4
abcd
END
stats
STAT pid 9712
STAT uptime 771
STAT time 1587243412
STAT version 1.4.25
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.003562
STAT rusage_system 0.017813
STAT curr_connections 10
STAT total_connections 11
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 2
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 60
STAT bytes_written 70
STAT limit_maxbytes 134217728
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 72
STAT curr_items 1
STAT total_items 1
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END
java API 操作
需要在idea中配置环境:
需要将memcached的jar添加到idea中,可以使用离线的方式直接添加
package day0418;
import net.spy.memcached.MemcachedClient;
import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class Demo {
public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
adds();
}
/**
* 向memcached中添加数据
* */
public static void addMemcached() throws IOException, ExecutionException, InterruptedException {
//创建memcached实例,指定服务器的IP地址和端口号
MemcachedClient client = new MemcachedClient(
new InetSocketAddress("192.168.2.111",11211));
//添加数据
Future<Boolean> f = client.set("key1",0,"day0418");
//关闭客户端
if(f.get().booleanValue()){
client.shutdown();
}
}
/**
* 读取Memcached的数据
* */
public static void getMem() throws IOException {
//创建memcached实例,指定服务器的IP地址和端口号
MemcachedClient client = new MemcachedClient(
new InetSocketAddress("192.168.2.111",11211));
//获取数据,通过key获取value
Object o = client.get("key1");
System.out.println("key1的值:"+o);
client.shutdown();
}
/**
* 向Memcached中添加类
* */
public static void addStudentMem() throws IOException, ExecutionException, InterruptedException {
//创建memcached实例,指定服务器的IP地址和端口号
MemcachedClient client = new MemcachedClient(
new InetSocketAddress("192.168.2.111",11211));
//添加数据
Future<Boolean> future = client.set("key3",0,new Student());
//关闭客户端
if (future.get().booleanValue()){
client.shutdown();
}
}
/**
* 向Memcached集群中添加数据
* */
public static void adds() throws IOException, InterruptedException {
//创建连接集群
List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
list.add(new InetSocketAddress("192.168.2.111",11211));
list.add(new InetSocketAddress("192.168.2.111",11212));
list.add(new InetSocketAddress("192.168.2.111",11213));
MemcachedClient client = new MemcachedClient(list);
for(int i = 1; i <= 20 ; i++){
System.out.println("插入第"+i+"个数据");
client.set("key"+i,0,"value"+i);
Thread.sleep(1000);
}
client.shutdown();
}
}
class Student implements Serializable{}
Redis
Redis简介
redis的前身是Memcached
redis和Memcached区别:
支持持久化:RDB快照,AOF日志
支持丰富的数据类型
Redis安装
(1)解压安装
tar -zxvf ./soft/redis-3.0.5.tar.gz -C ./
(2)编译
make
(3)安装及指定安装的路径
make PREFIX=/opt/redis install
redis中bin下命令的含义:
redis-benchmark redis提供压力测试的工具,模拟产生客户端压力
redis-check-aof 检查aof日志文件
redis-check-dump 检测RDB的文件
redis-cli 启动redis客户端
redis-sentinel 启动redis的哨兵
redis-server 启动redis的服务器
修改配置文件:redis.conf
42 daemonize no 将no改为yes(是否以后台方式启动)
50 port 6379 此端口是redis默认的,如果在同一个服务器启动多个redis需要修改
#启动redis服务端
[root@bigdata111 redis]# ./bin/redis-server ./redis.conf
[root@bigdata111 redis]# ps -ef | grep redis
root 12816 1 0 06:04 ? 00:00:00 ./bin/redis-server *:6379
root 12820 2479 0 06:04 pts/0 00:00:00 grep --color=auto redis
redis的操作:不作为重点
命令
[root@bigdata111 redis]# ./bin/redis-cli
127.0.0.1:6379> set key1 day0418
OK
127.0.0.1:6379> get key1
"day0418"
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> set key1 day0418
OK
127.0.0.1:6379> set key2 day0418
OK
127.0.0.1:6379> set key3 day0418
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key3"
3) "key2"
127.0.0.1:6379>
Redis的事务
回顾关系型数据库的事务:
事务是由一组DML语句组成
事务的特点:要么成功,要么失败
事务一些特性:ACID 原子性,一致性,隔离性,持久性
redis的事务本质:是将一组操作放在队列中,然后一次执行
Oracle事务和redis事务操作对比:
Oracle | Redis | |
---|---|---|
事务开启 | 自动开启 | 命令:multi |
执行语句 | DML | Redis命令 |
事务提交 | 显式提交:commit,隐式提交:DDL语句(Create table) | 命令:exec |
事务回滚 | 显式回滚:Rollback,隐式回滚:系统断电,客户端退出,自动回滚 | 命令:discard将队列中的操作废弃 |
redis的事务不是真正的事务,是事务的模拟。
举例:
模拟银行转账操作
127.0.0.1:6379> set zhangsan 2000
OK(操作成功)
127.0.0.1:6379> set lisi 2000
OK
127.0.0.1:6379> MULTI (开启事务)
OK
127.0.0.1:6379> decrby zhangsan 500
QUEUED(将操作放在队列中)
127.0.0.1:6379> incrby lisi 500
QUEUED
127.0.0.1:6379> exec(执行事务)
1) (integer) 1500
2) (integer) 2500
127.0.0.1:6379> get zhangsan
"1500"
127.0.0.1:6379> get lisi
"2500"