列表键的底层就是一个链表
链表节点
每个链表节点使用一个 adlist.h/listNode 结构来表示:1
2
3
4
5
6
7
8
9
10
11
12typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void *value;
} listNode;
Just in time编译,也叫做运行时编译,不同于 C / C++ 语言直接被翻译成机器指令,javac把java的源文件翻译成了class文件,而class文件中全都是Java字节码。那么,JVM在加载了这些class文件以后,针对这些字节码,逐条取出,逐条执行,这种方法就是解释执行。
还有一种,就是把这些Java字节码重新编译优化,生成机器码,让CPU直接执行。这样编出来的代码效率会更高。通常,我们不必把所有的Java方法都编译成机器码,只需要把调用最频繁,占据CPU时间最长的方法找出来将其编译成机器码。这种调用最频繁的Java方法就是我们常说的热点方法(Hotspot,说不定这个虚拟机的名字就是从这里来的)。
这种在运行时按需编译的方式就是Just In Time。
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将 SDS 用作 Redis 的默认字符串表示。例如键(key)底层就是SDS,而值如果是字符串对象,那这个对象的底层也是个SDS
每个 sds.h/sdshdr 结构表示一个 SDS 值:1
2
3
4
5
6
7
8
9
10
11
12
13struct sdshdr {
// 记录 buf 数组中已使用字节的数量
// 等于 SDS 所保存字符串的长度
int len;
// 记录 buf 数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
};
图 2-1 展示了一个 SDS 示例:
遵循空字符结尾这一惯例的好处是, SDS 可以直接重用一部分 C 字符串函数库里面的函数。
举个例子, 如果我们有一个指向图 2-1 所示 SDS 的指针 s , 那么我们可以直接使用 stdio.h/printf 函数, 通过执行以下语句:1
printf("%s", s->buf);
现在要开始安装compute服务了,前面一章都说了,虽然controller节点主要用来做控制服务节点的,如果做实验的话,可以用它的多余资源来充当一下compute节点,那么这个实验就可以有两台compute节点了。
开始安装吧。。。
1 | $ apt install nova-compute |
/etc/nova/nova.conf
[DEFAULT]
区域,配置RabbitMQ
1 | [DEFAULT] |
替换RABBIT_PASS
为当时为RabbitMQ
创建openstack
用户时指定的密码
[api]
和[keystone——authtoken]
区域,配置keystone相关配置1 | [api] |
替换NOVA_PASS
为你创建nova用户时的密码
在[DEFAULT]
区域,配置my_ip
1 | [DEFAULT] |
在[DEFAULT]
区域,关掉防火墙和使用neutron
1 | [DEFAULT] |
以前nova是提供网络服务的,现在有了neutron之后,就不用了,所以这里要关掉先。
在[vnc]
区域,配置远程访问:
1 | [vnc] |
在[glance]
区域,配置镜像访问接口:
1 | [glance] |
在[DEFAULT]
区域,log_dir
选项
[placement]
区域,配置Placement API:1 | [placement] |
替换PLACEMENT_PASS
为之前配置placement用户时候设置的密码
执行以下命令:1
$ egrep -c '(vmx|svm)' /proc/cpuinfo
如果返回多个,就代表你机子已经硬件支持kvm,所以不用配置什么
如果返回0,代表你机子不支持kvm,所以就需要修改为qemu1
2
3[libvirt]
# ...
virt_type = qemu
1 | $ service nova-compute restart |
以下操作只能在controller节点执行
执行以下命令:
1 | $ . admin-openrc |
发现compute节点
1 | # su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova |
如果你新加了个compute,必须要再执行一遍上面的命令,或者在nova的配置文件改一个合适的间隔来自动发现吧。1
2[scheduler]
discover_hosts_in_cells_interval = 300
nova服务到这里已经都装完了,如果你controller也安装了compute的服务的话,那就有两台compute node了😄
接下来要进入重头戏的网络服务neutron的安装了👿
nova是OpenStack一个核心服务,提供计算服务,主要负责虚拟机的各种操作,如启动,销毁,快照,还有选择合适的compute节点部署虚拟机。
nova中的服务有controller和compute之分,是一对多的关系,即一个controller可以有多个compute,所以一些controller服务要装到controller
节点上,compute服务可以装到compute
节点,也可以装到controller
节点来让它充当一部分compute的能力。
由于nova涉及controller
节点和compute
节点的安装,所以分了两篇文章来讲解
这一篇先介绍怎么安装nova的controller服务在controller
节点上。
用root
用户权限执行mysql
1 | $ mysql |
创建nova_api
, nova
,和nova_cell0
数据库:
1 | MariaDB [(none)]> CREATE DATABASE nova_api; |
赋予适合的权限给这些数据库
1 | MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' \ |
替换NOVA_DBPASS
密码为合适的,下面会用到。
epoll是Linux下的一种IO多路复用技术,可以非常高效的处理数以百万计的socket句柄。
先看看使用c封装的3个epoll系统调用:
glance提供镜像服务使用户能够发现,注册和检索虚拟机镜像。它提供了一个 REST API,可让您查询虚拟机镜像元数据并检索实际镜像。您可以存储镜像在各种位置(从简单的文件系统到像OpenStack Object Storage这样的对象存储系统)。
为了简单起见,这里只是教你如何配置镜像服务,并把镜像保存到controller节点的文件目录里面,此目录为/var/lib/glance/images/。
这一章还是在controller
节点操作。。。
用root
用户权限执行mysql
1 | $ mysql |
创建glance
数据库
1 | MariaDB [(none)]> CREATE DATABASE glance; |
赋予适合的权限给glance
数据库
1 | MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' \ |
替换一下GLANCE_DBPASS
为一个合适的密码,后面会用到
keystone 是openstack中所有service的权限管理和接口入口,所以先安装它
这一章都是在controller
节点操作。。。
切换到root
用户,执行下面命令
1 | $ mysql |
创建keystone
数据库:
1 | MariaDB [(none)]> CREATE DATABASE keystone; |
赋予合适权限给keystone
数据库:
1 | MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \ |
用一个合适的密码覆盖KEYSTONE_DBPASS