среда, 26 января 2011 г.

Squid: Оптимизируем transparent proxy на Solaris 10 - неблокирующий IO

Я уже писал о том, как построить transparent proxy на базе Squid на Solaris 10. Пришла пора заняться его оптимизацией.

Лично мне, в процессе эксплуатации, не очень понравилось время отклика сервера, достигающее 0,3 секунды.

Тщательное исследование показало несколько достаточно узких мест.

Первое - это избыточное кэширование данных файловой системой.

Так как мы используем приложение, которое само по себе является кэшем, кэш второго уровня ZFS явно избыточный. Отключим его:


root @ ktulhu / # zfs get primarycache,secondarycache,recordsize data/cache
NAME PROPERTY VALUE SOURCE
data/cache primarycache all local
data/cache secondarycache none local
data/cache recordsize 2K local

Следующий шаг - собранный на www.sunfreeware.com сквид нас не устраивает. В нем не включена опция асинхронного IO, и включены некоторые избыточные опции в случае, если включить этот самый саинхронный IO. Возьмем исходники и пересоберем его. Так как сервер прозрачный, можно с чистой совестью выкинуть поддержку SSL, а также SNMP (для безопасности) и unlinkd (это лишнее при использовании асинхронного IO).

Для ленивых команда конфигурирования (у моего сервера 4 ядра и два диска в зеркале):


./configure '--disable-unlinkd' '--enable-default-err-language=Russian-1251' --enable-err-languages='Russian-1251 English' '--enable-follow-x-forwarded-for' '--enable-ipf-transparent' '--enable-storeio=ufs,diskd' '--enable-delay-pools' '--enable-async-io=4' '--prefix=/usr/local/squid' '--enable-external-acl-helpers=ldap_group' '--enable-removal-policies=lru,heap' '--enable-large-cache-files' 'CC=gcc' 'CFLAGS=-O2 -march=i686 -L/usr/local/lib -R/usr/local/lib -L/usr/local/ssl/lib -R/usr/local/ssl/lib -L/usr/openwin/lib -R/usr/openwin/lib -I/usr/local/rrdtool-1.4.2/include -I/usr/local/BerkeleyDB.4.7/include -I/usr/local/mysql/include' 'LDFLAGS=-L/usr/local/lib -R/usr/local/lib -R/usr/lib -L/usr/lib -R/usr/openwin/lib -L/usr/openwin/lib -L/usr/local/ssl/lib -R/usr/local/ssl/lib -L/usr/X11R6/lib -R/usr/X11R6/lib -L/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.7/lib -L/usr/local/mysql/lib -R/usr/local/mysql/lib' 'CPPFLAGS=-I/usr/local/include -I/usr/local/ssl/include -I/usr/local/include/ncurses -I/usr/openwin/include -I/usr/local/rrdtool-1.4.2/include -I/usr/local/BerkeleyDB.4.7/include -I/usr/local/include/pcap -I/usr/local/include/freetype2'

Результат сборки:


squid @ ktulhu /usr/local/squid/bin $ squid -v
Squid Cache: Version 2.7.STABLE9
configure options: '--disable-unlinkd' '--enable-default-err-language=Russian-1251' '--enable-err-languages=Russian-1251 English' '--enable-follow-x-forwarded-for' '--enable-ipf-transparent' '--enable-storeio=ufs,diskd' '--prefix=/usr/local/squid' '--enable-external-acl-helpers=ldap_group' '--enable-removal-policies=lru,heap' '--enable-large-cache-files' '--enable-cache-digests' 'CC=gcc' 'CFLAGS=-O2 -march=i686 -L/usr/local/lib -R/usr/local/lib -L/usr/local/ssl/lib -R/usr/local/ssl/lib -L/usr/openwin/lib -R/usr/openwin/lib -I/usr/local/rrdtool-1.4.2/include -I/usr/local/BerkeleyDB.4.7/include -I/usr/local/mysql/include' 'LDFLAGS=-L/usr/local/lib -R/usr/local/lib -R/usr/lib -L/usr/lib -R/usr/openwin/lib -L/usr/openwin/lib -L/usr/local/ssl/lib -R/usr/local/ssl/lib -L/usr/X11R6/lib -R/usr/X11R6/lib -L/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.7/lib -L/usr/local/mysql/lib -R/usr/local/mysql/lib' 'CPPFLAGS=-I/usr/local/include -I/usr/local/ssl/include -I/usr/local/include/ncurses -I/usr/openwin/include -I/usr/local/rrdtool-1.4.2/include -I/usr/local/BerkeleyDB.4.7/include -I/usr/local/include/pcap -I/usr/local/include/freetype2'

Требуется внесение некоторых изменений в конфигурацию. Главное изменение - вместо ufs в директиве cache_dir будет стоять diskd (модуль aufs на Solaris не применяется), и для полного счастья добавим четыре файловых системы, на каждую из которых будем запускать отдельный процесс IO:

root @ ktulhu / # zfs list
NAME USED AVAIL REFER MOUNTPOINT
data 3.01G 257G 25K /data
data/backup 2.96G 257G 2.96G /data/backup
data/cache 51.1M 64.0G 31K /data/cache
data/cache/d1 7.77M 64.0G 7.77M /data/cache/d1
data/cache/d2 8.14M 64.0G 8.14M /data/cache/d2
data/cache/d3 9.56M 64.0G 9.56M /data/cache/d3
data/cache/d4 7.82M 64.0G 7.82M /data/cache/d4
data/cache/log 17.8M 64.0G 17.8M /data/cache/log

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /usr/loal/squid/var/cache 100 16 256
cache_dir diskd /data/cache/d1 16384 16 256 Q1=72 Q2=64
cache_dir diskd /data/cache/d2 16384 16 256 Q1=72 Q2=64
cache_dir diskd /data/cache/d3 16384 16 256 Q1=72 Q2=64
cache_dir diskd /data/cache/d4 16384 16 256 Q1=72 Q2=64

На каждую отдельную директорию монтирования датасетов стартует отдельный процесс ввода-вывода diskd. Разумеется, директории кэша придется пересоздать.

И немного подправим конфигурацию самого сквида - как с целью оптимизации, так и в плане функциональности (буферизация логов, LRU-полиси, кэширование флэша, RealMedia, YouTube, refresh_patterns и немного тюнинга):

#Recommended minimum configuration:
acl all src all
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
#
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http

acl CONNECT method CONNECT

# Local Apache server address
acl localapache dst 192.168.1.20

# Common methods acls
acl GET method GET
acl POST method POST

# Numeric IP's acl
acl numeric_IPs url_regex ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+

# Media and video acls
acl youtube dstdomain .youtube.com
acl media rep_mime_type -i video/flv
acl mediapr urlpath_regex \.flv(\?.*)?$
acl media rep_mime_type -i ^application/x-shockwave-flash$
acl mediapr urlpath_regex \.swf(\?.*)?$

# Real audio acls
acl RealAudio_mime req_mime_type application/x-pncmd

# TAG: http_access
# Allowing or Denying access based on defined access lists
#
# Access to the HTTP port:
# http_access allow|deny [!]aclname ...
#
# NOTE on default values:
#
# If there are no "access" lines present, the default is to deny
# the request.
#
# If none of the "access" lines cause a match, the default is the
# opposite of the last line in the list. If the last line was
# deny, the default is allow. Conversely, if the last line
# is allow, the default will be deny. For these reasons, it is a
# good idea to have an "deny all" or "allow all" entry at the end
# of your access lists to avoid potential confusion.
#
#Default:
# http_access deny all
#
#Recommended minimum configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost
http_access deny manager
# Deny access to numeric IP's
http_access deny CONNECT numeric_IPs all
# Deny requests to unknown ports
http_access deny !Safe_ports
# Deny CONNECT to other than SSL ports
http_access deny CONNECT !SSL_ports
#
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
http_access deny to_localhost
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet

# Required to work caching from local cache
http_access allow localhost

# Always direct directives
always_direct allow localapache

# Cache directives
cache allow youtube
cache allow media
cache allow mediapr
cache allow POST RealAudio_mime
# Required to work common refresh patterns
cache allow all

# Hide internal networks details outside
forwarded_for off
header_access X-Forwarded-For deny all
header_access Via deny all

# And finally deny all other access to this proxy
http_access deny all

# Squid normally listens to port 3128
http_port 3128 transparent

# Cache manager
cache_mgr yourname@yourdomain.com

# Cache manager password
cachemgr_passwd XXXXXXXXXXX all

# Cache user
cache_effective_user squid
cache_effective_group squid

# We recommend you to use at least the following line.
hierarchy_stoplist cgi-bin ?

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /usr/loal/squid/var/cache 100 16 256
cache_dir diskd /data/cache/d1 16384 16 256 Q1=72 Q2=64
cache_dir diskd /data/cache/d2 16384 16 256 Q1=72 Q2=64
cache_dir diskd /data/cache/d3 16384 16 256 Q1=72 Q2=64
cache_dir diskd /data/cache/d4 16384 16 256 Q1=72 Q2=64

# Memory parameters
cache_mem 512 Mb
memory_pools off
maximum_object_size 32 MB
maximum_object_size_in_memory 512 KB

# -------------------------------------
# Tuning parameters
# -------------------------------------
ipcache_size 8192
ipcache_low 95
ipcache_high 98

fqdncache_size 8192

buffered_logs on

memory_replacement_policy heap GDSF
#cache_replacement_policy heap GDSF
cache_replacement_policy heap LFUDA
#cache_replacement_policy heap LRU

half_closed_clients off
#snmp_port 0
icp_port 0

cache_swap_high 98
cache_swap_low 95
# -------------------------------------
# Tuning parameters
# -------------------------------------

# Apparently youtube.com use 'Range' requests
# - not seen, but presumably when a video is stopped for a long while then resumed, (or fast-forwarded).
# - convert range requests into a full-file request, so squid can cache it
# NP: BUT slows down their _first_ load time.
quick_abort_min -1 KB

# Access log
access_log /data/cache/log/access.log squid

# Cache log
cache_log /data/cache/log/cache.log

# Store log
cache_store_log none
#cache_store_log /data/cache/log/store.log

# Leave coredumps in the first cache dir
#coredump_dir /usr/local/squid/var/cache
coredump_dir /var/core

# Pid file
pid_filename /usr/local/squid/var/logs/squid.pid

# Add any of your own refresh_pattern entries above these.
# Own refresh patterns
refresh_pattern -i \.(gif|png|jp?g|ico|bmp|tiff?)$ 10080 95% 43200 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private
refresh_pattern -i \.(html|htm|css|js)$ 1440 75% 40320
refresh_pattern -i \.index.(html|htm)$ 0 75% 10080
refresh_pattern -i \.(class|css|js|tif)(\?.*)?$ 1440 95% 100000080 reload-into-ims override-lastmod
refresh_pattern -i \.(jpe|jpg|jpeg|png|bmp|gif)(\?.*)?$ 0 95% 1000000080 reload-into-ims override-lastmod
refresh_pattern -i \.(asp|acgi|pl|shtml|php3|php)(\?.*)?$ 2 20% 432000 reload-into-ims override-lastmod

refresh_pattern \.bz2$ 43200 100% 43200 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern \.exe$ 43200 100% 43200 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern \.gz$ 43200 100% 43200 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern \.tar$ 43200 100% 43200 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern \.tgz$ 43200 100% 43200 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern \.zip$ 43200 100% 43200 override-lastmod override-expire ignore-reload ignore-no-cache

# Break some HTTP standard for flash videos. Keep them in cache even if asked not to.
refresh_pattern -i \.flv$ 10080 90% 999999 ignore-no-cache ignore-private

#refresh_pattern ^ftp: 1440 20% 10080
#refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
#refresh_pattern . 0 20% 4320
refresh_pattern . 0 80% 14400

# SquidGuard rewriter
url_rewrite_program /usr/local/bin/squidGuard -c /usr/local/squidGuard/squidGuard.conf
url_rewrite_children 96
redirect_rewrites_host_header on
#redirector_bypass on

Я сознательно оставил некоторые параметры, позволяющие в случае необходимости сделать сервер непрозрачным прокси.

Собственно, это все. Перезапускаем сквид и - вуаля! - отклик 0,1 секунды максимум (разумеется, после прогрева кэша).

среда, 19 января 2011 г.

Solaris 11 Express: Создание загрузочного USB-устройства без usbcopy

Забавно было наблюдать, как Оракл поверг всех "системных администраторов" в смущение выпуском Solaris 11 Express LiveUSB с утилитой создания этого самого LiveUSB, находящейся внутри установочного имиджа. :) И резко исчезнувшей со всех ресурсов, посвященных OpenSolaris. Ну, ладно, преувеличиваю. Тщательные раскопки переписки в районе OpenSolaris позволили найти некий промежуточный вариант usbcopy, в аттачментах переписки о багах этой самой usbcopy.

Вообще забавно было читать на форумах записки ошеломленных сисадминов, которые как проклятые пытались найти эту утилиту (фактически - скрипт). И без которой были беспомощны, как котята. Мне даже попалось глубокомысленное высказывание о проблеме курицы и яйца, с советом поставить Solaris 11 сначала с CD, а потом, скачав LiveUSB имидж, создавать загрузочную флэшку. :) Ха, качать два имиджа, чтобы сделать загрузочную флэшку, щаз!

Ладно, нашел я в конце-концов этот многострадальный скрипт.

Посмотрел на него.

Очевидно было, что на нормальном Солярисе он наверняка не запустится, поскольку юзерлэнд в OpenSolaris совершенно другой, GNUтый. Однако действия, в нем выполняемые, были совершенно очевидными и, если выкинуть ненужное умничанье и некоторые избыточные действия, вполне доступными для выполнения ручками.

Итак, как руками создать загрузочную флэшку из имиджа LiveUSB Solaris 11 Express?

Элементарно, Ватсон!

Половина необходимых действий описана здесь. Нам потребуется машина с установленной Solaris 10 x86. Переливаем на нее имидж LiveUSB с сайта Oracle.

1. Выключаем сервис VOLD:

root @ ktulhu /stage # svcadm disable volfs
root @ ktulhu /stage # svcs volfs
STATE STIME FMRI
disabled 18:31:52 svc:/system/filesystem/volfs:default


2. Подключаем к машине под Solaris 10 флэшку объемом от 1 Гб и определяем логическое имя устройства для флэшки командой rmformat:

root @ ktulhu /stage # rmformat -l
Looking for devices...
1. Logical Node: /dev/rdsk/c2t0d0p0
Physical Node: /pci@0,0/pci1043,819e@1d,7/storage@3/disk@0,0
Connected Device: Generic USB Flash Disk 0.00
Device Type: Removable
2. Logical Node: /dev/rdsk/c0t1d0p0
Physical Node: /pci@0,0/pci-ide@1f,1/ide@0/sd@1,0
Connected Device: TEAC DV-W28E-R 1.0B
Device Type: DVD Reader/Writer

В моем случае именем устройства является /dev/rdsk/c2t0d0p2.

3. Создаем на флэшке партишен Solaris на весь объем USB-устройства:

root @ ktulhu /stage # fdisk -d -B /dev/rdsk/c2t0d0p0
Physical Geometry:
cylinders[1926] heads[128] sectors[32]
sector size[512] blocks[7888896] mbytes[-244]
Virtual (HBA) Geometry:
cylinders[491] heads[255] sectors[63]
sector size[512] blocks[7887915] mbytes[-244]
About to write fdisk table:
SYSID ACT BHEAD BSECT BEGCYL EHEAD ESECT ENDCYL RELSECT NUMSECT
191 128 65 2 0 15 36 491 4096 7884800
100 0 0 0 0 0 0 0 100 100
100 0 0 0 0 0 0 0 100 100
100 0 0 0 0 0 0 0 100 100

4. Запускаем format в режиме эксперта и создаем на флэшке слайс 0 с тэгом root, как описано здесь:

root @ ktulhu /stage # fdisk -d -B /dev/rdsk/c2t0d0p0
Physical Geometry:
cylinders[1926] heads[128] sectors[32]
sector size[512] blocks[7888896] mbytes[-244]
Virtual (HBA) Geometry:
cylinders[491] heads[255] sectors[63]
sector size[512] blocks[7887915] mbytes[-244]
About to write fdisk table:
SYSID ACT BHEAD BSECT BEGCYL EHEAD ESECT ENDCYL RELSECT NUMSECT
191 128 65 2 0 15 36 491 4096 7884800
100 0 0 0 0 0 0 0 100 100
100 0 0 0 0 0 0 0 100 100
100 0 0 0 0 0 0 0 100 100

root @ ktulhu / # format -e /dev/rdsk/c2t0d0p2
Error: can't open selected disk '/dev/rdsk/c2t0d0p2'.

format
> disk

AVAILABLE DISK SELECTIONS:
0. /dev/rdsk/c2t0d0
<drive type unknown>
/pci@0,0/pci1043,819e@1d,7/storage@4/disk@0,0
Specify disk (enter its number)[0]: 0

AVAILABLE DRIVE TYPES:
0. Auto configure
1. other
Specify disk type (enter its number): 0
Auto configuration via format.dat[no]? yes
/dev/rdsk/c2t0d0: configured with capacity of 3.76GB
<Generic-USBFlashDisk-0.00 cyl 1923 alt 2 hd 128 sec 32>
selecting /dev/rdsk/c2t0d0
[disk formatted]
format
> partition
...
partition
> print
Current partition table (default):
Total disk cylinders available: 1923 + 2 (reserved cylinders)

Part Tag Flag Cylinders Size Blocks
0 root wm 0 0 (0/0/0) 0
1 swap wu 0 0 (0/0/0) 0
2 backup wu 0 - 1924 3.76GB (1925/0/0) 7884800
3 unassigned wm 0 0 (0/0/0) 0
4 unassigned wm 0 0 (0/0/0) 0
5 unassigned wm 0 0 (0/0/0) 0
6 usr wm 1 - 1922 3.75GB (1922/0/0) 7872512
7 unassigned wm 0 0 (0/0/0) 0
8 boot wu 0 - 0 2.00MB (1/0/0) 4096
9 alternates wm 0 0 (0/0/0) 0

partition
> 6
Part Tag Flag Cylinders Size Blocks
6 usr wm 1 - 1922 3.75GB (1922/0/0) 7872512

Enter partition id tag[usr]: unassigned
Enter partition permission flags[wm]:
Enter new starting cyl[1]: 0
Enter partition size[7872512b, 1922c, 1921e, 3844.00mb, 3.75gb]: 0gb
partition
> print
Current partition table (unnamed):
Total disk cylinders available: 1923 + 2 (reserved cylinders)

Part Tag Flag Cylinders Size Blocks
0 root wm 0 0 (0/0/0) 0
1 swap wu 0 0 (0/0/0) 0
2 backup wu 0 - 1924 3.76GB (1925/0/0) 7884800
3 unassigned wm 0 0 (0/0/0) 0
4 unassigned wm 0 0 (0/0/0) 0
5 unassigned wm 0 0 (0/0/0) 0
6 unassigned wm 0 0 (0/0/0) 0
7 unassigned wm 0 0 (0/0/0) 0
8 boot wu 0 - 0 2.00MB (1/0/0) 4096
9 alternates wm 0 0 (0/0/0) 0

partition
> 2
Part Tag Flag Cylinders Size Blocks
2 backup wu 0 - 1924 3.76GB (1925/0/0) 7884800

Enter partition id tag[backup]: ^C
partition
> 0
Part Tag Flag Cylinders Size Blocks
0 root wm 0 0 (0/0/0) 0

Enter partition id tag[root]:
Enter partition permission flags[wm]:
Enter new starting cyl[1]:
Enter partition size[0b, 0c, 1e, 0.00mb, 0.00gb]: 1924e
End cylinder 1924 is beyond max cylinder 1922
Enter partition size[0b, 0c, 1e, 0.00mb, 0.00gb]: 1922e
partition
> print
Current partition table (unnamed):
Total disk cylinders available: 1923 + 2 (reserved cylinders)

Part Tag Flag Cylinders Size Blocks
0 root wm 1 - 1922 3.75GB (1922/0/0) 7872512
1 swap wu 0 0 (0/0/0) 0
2 backup wu 0 - 1924 3.76GB (1925/0/0) 7884800
3 unassigned wm 0 0 (0/0/0) 0
4 unassigned wm 0 0 (0/0/0) 0
5 unassigned wm 0 0 (0/0/0) 0
6 unassigned wm 0 0 (0/0/0) 0
7 unassigned wm 0 0 (0/0/0) 0
8 boot wu 0 - 0 2.00MB (1/0/0) 4096
9 alternates wm 0 0 (0/0/0) 0

partition
> label
[0] SMI Label
[1] EFI Label
Specify Label type[0]: 0
Ready to label disk, continue? y

partition
>

Количество цилиндров раздела можно увидеть визуально, без ухищрений с prtvtoc и прочих изысков. Метка создается SMI.

(Кстати, в оригинальном скрипте usbcopy эта тривиальная процедура делается полностью автоматически - понимаю, зачем, но писать сейчас аналогичный скрипт, работающий не на OpenSolaris мне просто влом. Я всего лишь хочу создать один-единственный LiveUSB).

5. Загруженный на нашу машину с Solaris 10 имидж просто копируем утилитой dd на нашу флэшку (файловую систему создавать не обязательно):

root @ ktulhu /stage # dd bs=16384 conv=sync if=sol-11-exp-201011-live-x86.usb of=/dev/rdsk/c2t0d0s0
52762+1 records in
52763+0 records out

Процедура копирования заняла у меня около 5 минут.

6. Последнее действие - смонтируем флэшку и запишем на нее загрузчик с нее же:

root @ ktulhu /stage # mount /dev/dsk/c2t0d0s0 /mnt

root @ ktulhu /stage # dd bs=16384 conv=sync if=sol-11-exp-201011-live-x86.usb of=/dev/rdsk/c2t0d0s0
52762+1 records in
52763+0 records out

Можно убедиться, что имидж записан на флэшку:

root @ ktulhu /stage # ls -al /mnt
total 591082
drwxr-xr-x 15 root root 512 Nov 5 21:56 .
drwxr-xr-x 33 root root 43 Jan 20 11:12 ..
-r--r--r-- 1 root root 2048 Nov 5 21:55 .catalog
drwxr-xr-x 2 root sys 512 Nov 5 21:01 .cdrom
-rw-r--r-- 1 root root 65 Nov 5 21:27 .image_info
-rw-r--r-- 1 root root 4242 Nov 5 21:55 .livecd-cdrom-content
-r--r--r-- 1 root root 37 Nov 5 21:27 .volsetid
lrwxrwxrwx 1 root root 9 Nov 5 21:55 bin -> ./usr/bin
drwxr-xr-x 5 root sys 512 Nov 5 21:55 boot
drwxr-xr-x 14 root sys 1024 Nov 5 21:55 dev
drwxr-xr-x 3 root sys 512 Nov 5 21:55 devices
drwxr-xr-x 5 65432 staff 512 Nov 5 21:55 jack
drwx------ 2 root root 8192 Nov 5 21:55 lost+found
drwxr-xr-x 3 root sys 512 Nov 5 21:55 mnt
drwxr-xr-x 5 root sys 512 Nov 5 21:55 platform
dr-xr-xr-x 2 root root 512 Nov 5 21:01 proc
-rw-r--r-- 1 root root 0 Nov 5 21:03 reconfigure
drwx------ 2 root root 512 Nov 5 21:55 root
drwxr-xr-x 4 root root 512 Nov 5 21:55 save
-rw-r--r-- 1 root root 576742912 Nov 5 21:53 solaris.zlib
-rw-r--r-- 1 root root 28161024 Nov 5 21:55 solarismisc.zlib
drwxr-xr-x 4 root root 512 Nov 5 21:56 system
drwxrwxrwt 2 root sys 512 Nov 5 21:01 tmp

и отмонтировать ее:

root @ ktulhu /stage # umount /mnt

Для спокойствия можно убедиться, что файловая система на флэшке UFS:

root @ ktulhu /stage # fstyp /dev/rdsk/c2t0d0s0
ufs

That's all, folks! Вот и все, мальчики и девочки!

Можно стартовать с вновь созданного LiveUSB.

понедельник, 17 января 2011 г.

Oracle на ZFS: Учимся готовить кошек, часть I

Вы не любите кошек?
Вы просто не умеете их готовить!

Честно говоря, я устал читать мнения анонимных аналитиков на IT-форумах о том, что-де ZFS медленно работает вообще (в принципе), а с использованием БД - в особенности. Поскольку мой личный опыт противоречит этой, в принципе ничем не обоснованной, точке зрения, давайте обратимся к первоисточникам и прочитаем вам маны вслух за ваши деньги. :)

Вначале мне бы хотелось рассмотреть рекомендации собственно Оракла (кстати, сертифицированного для работы на ZFS) с некоторыми комментариями. В дальнейшем мы расширим эти рекомендации в сторону практического опыта эксплуатации БД Oracle на ZFS и самоочевидных результатов собственных тестов.

Итак, давайте откроем данный официальный документ и начнем его читать вдумчиво.

Во-первых, обратим внимание на то, что в документе говориться о нативной реализации ZFS в Solaris 10 и OpenSolaris. Ни о каких деривативах, типа реализации ZFS на FreeBSD и речи не идет. О Solaris 11 мы тоже пока ничего не говорим, до выхода официального релиза.

Во-вторых, заметим, что собственно Оракл говорит об использовании ZFS на одноинстансных инсталляциях (не кластерных), а использование ZFS на RAC предполагает исключительно ее использование как NFS-шары (что лично мне представляется не лучшей идеей в кластерных архитектурах, а для Оракла в особенности, для RAC лучший вариант - OCFS2 - ASM). Это, в общем-то, достаточно логично, так как ZFS разрабатывалась изначально как локальная не кластерная файловая система (К сведению аналитиков - как замена UFS, которая также не является кластерной).

В-третьих, важнейшее замечание по конфигурированию массивов звучит буквально так - "создавайте столько LUN, сколько имеете шпинделей". Использование нескольких больших LUN ведет к уменьшению количества читающих тредов и падению производительности по чтению. И, наоборот, чрезмерное количество LUNов (по отношению к количеству шпинделей) приводит к затоплению массива большим количеством ожидающих операций чтения. Собственно, данная рекомендация восходит к рекомендациям большинства вендоров "шпиндели, шпиндели и еще раз шпиндели" - что означает, что большее количество относительно небольших дисков работает значительно более эффективно, нежели небольшое количество крупных дисков, обеспечивая значительно более высокий transfer rate и в целом увеличивая количество IOPS. В нашем случае, однако, важно совпадение количества LUNов c количеством шпинделей.

В-четвертых, Оракл прямо дает рекоменданию не создавать ZFS поверх существующей аппаратной или программной RAID-структуры. Что, в общем, совершенно очевидно, поскольку ZFS является volume manager и файловой системой в одном флаконе, имеет собственные средства обеспечения отказоустойчивости (на мой взгляд, гораздо лучшие, чем традиционные RAID). Подобно RAID-10, зеркалированные пулы ZFS обладают выдающейся производительностью, высокой надежностью, несравненно лучшими эксплуатационными показателями и способностью к самовосстановлению данных в случае их акцидентального повреждения. Для аналитиков: проверено на практике, в зеркалированном пуле в случае повреждения данных выполняется синхронизация (частичная или полная) с зеркала (зеркал) в полностью автоматическом режиме, как только файловая система обнаруживает нарушения контрольных сумм данных либо метаданных. При этом база данных, находящаяся на таком пуле, даже скорости работы не снижает.

В-пятых, Оракл явно не рекомендует использование RAIDZ, если производительность и IOPS являются главными критериями, предъявляемыми к системе хранения. Для информации - Оракл точно так же не рекомендует использование RAID-5 в более традиционных системах хранения, особенно с повышенными требованиями к скорости записи.

В-шестых, общее правило - размер recordsize для ZFS и db_block_size должны совпадать для файловых систем, на которых расположены файлы данных БД.

В-седьмых, рекомендуется, как и для традиционных систем хранения, отделять redo logs на отдельные файловые системы (пулы хранения)

В-восьмых, рекомендуется устанавливать режим ZIL параметром файловой системы logbias в значение throughput для большинства компонентов БД, исключая redo logs; а также управлять кэшированием данных в ARC L1 параметром primarycache, устанавливая его в значение metadata для UNDO и archived logs. Это логично - дабы не допускать чрезмерного перегрева кэша данными, которые в основном пишутся на диск и редко читаются (подобно буферному пулу RECYCLE в БД).

В-девятых, использование кэша ARC L2 позволяет повысить производительность, если произвольные чтения происходят в большом количестве и перегружают основную систему хранения. Одно но - рекомендуется создавать кэш L2 как отдельную структуру пула хранения для данных базы. И включение secondarycache не рекомендуется для redo logs в данный момент.

Далее в документе подробно рассматривается конфигурирование файловых систем и пулов хранения для работы под БД. Хочу обратить внимание на одну тонкость, прямо проистекающую из природы ZFS.

ZFS работает в идеологии COW (Copy-On-Write). Что означает, что при записи создается копия изменяемых данных в свободном пространстве, при сохранении предыдущей версии блоков данных.

При высоком заполнении пулов хранения/файловых систем (обычно свыше 80%) будет происходить резкое снижение производительности, поскольку ФС будет пытаться найти свободное пространство для записи копий.

Это нормальное естественное поведение ZFS. На практике есть два способа минимизировать влияние данной проблемы:

  1. Не допускать чрезмерного заполнения файловых систем установкой квот и резерваций.
  2. Попытаться оптимизировать выполнение записей на полных файловых системах установкой глобального системного параметра metaslab_df_free_pct в /etc/system:

Adjusting the metaslab_df_free_pct parameter to 4 in the /etc/system file
might help the write activity on full pools.
set zfs:metaslab_df_free_pct=4

Оракл также рекомендует ограничивать максимальный размер кэша ARC, что снижает нагрузку на память и позволяет снизить конкуренцию за оную:

You can reduce Oracle Solaris ZFS memory consumption by tuning the zfs_arc_max
parameter to a low value, but we still recommend provisioning enough memory to cache
metadata for the actively used portion of the database, which is estimated at 1.5% with an 8 KB
Oracle Solaris ZFS record size and proportionately less or more with larger or smaller records.
The file system that hold index files is the one that has the largest benefit from file system
caching because it is the last one to invalidate in case of lack of memory.
The zfs_arc_max parameter is in bytes and accepts decimal or hexadecimal values.
The following example sets this parameter to 2 GB:
set zfs:zfs_arc_max=2147483648
or
set zfs:zfs_arc_max=0x80000000

Опыт показывает, что уменьшать максимальный размер кэша ARC в значительной степени не стоит, поскольку как минимум метаданные ФС кэшировать все-таки необходимо. В большинстве случаев достаточно ограничить его максимальную величину значением 1/4-1/2 всей доступной оперативной памяти системы.

И последнее. Относится к администраторам любых систем, но в особенности систем с огромным количеством оперативной памяти. Приведу данную рекомендацию дословно:

To prevent applications from failing due to lack of memory, you must configure some amount of
swap space. The amount of swap equivalent to all of system memory is always enough for this
purpose. This swap space is not expected to be used, but is needed as a reservation area.
For information about increasing swap space, see the Oracle Solaris ZFS Administration Guide.

Говоря простым языком: Solaris не Windows, при большой памяти без свопа вообще работать не способна. Как минимум, один объем физической памяти должен быть отдан под подкачку, сколько бы этой памяти не было установлено (выделено мной).

Вот вкратце основные рекомендации Oracle, касающиеся производительности БД на ZFS.

Педантичное следование данным рекомендациям (а до их официального выхода - некоторым самоочевидным требованиям, описанным в документе) позволяло лично мне не раз достигать вполне выдающихся скоростных результатов (разумеется, в рамках оптимального дизайна БД и тщательной оптимизации запросов - впрочем, это позволяет добиваться выдающихся скоростных показателей на любых файловых системах, включая NTFS, при условии отсутствия очевидных бутылочных горлышек на уровне оборудования).

четверг, 13 января 2011 г.

No script

Вот и выросло поколение системных администраторов и DBA, не владеющих одним из основополагающих навыков - скриптингом.

Не владеющих никак. Ни на уровне самостоятельно написать что-то сложнее, чем "echo 'Hello, world!'", ни даже на уровне "прочитать и понять, что скрипт делает". И, более того, неспособных и не желающих даже прочитать readme к скрипту, буде таковой имеется!

Я приведу один простой пример.

Oracle на *nix работает, в общем, не со вчерашнего дня.

Но там нет одной ма-аленькой мелочи - автостарта сервисов Oracle.

С одной стороны, с некоторых пор в *nix-овых дистрах Oracle есть скрипты dbstart/dbshut. Между нами - девочками, вы видели эти скрипты? Они ублюдочные и это мягко сказано. Я бы поостерегся такой фэйк запускать. Ненужный и нелогичный код. Ни намека на структурность. Необходимость дописывания или серьезных переделок для мало-мальски нетривиальных энвайронментов.

Кроме того, в некоторых системах автостарт сервисов реализован не через линки rcX.d.

Как это так? Правда, сюрприз?

Да вот так, опаньки! Давайте посмотрим, что нашел гугл.

В первой позиции находится...А, мама, роди меня обратно!

Автор, представляющийся как OCP 10/11, даже не знает, что в Solaris 10 вот уже лет шесть минимум действует схема SMF-запуска сервисов. И запускные скрипты уже давно не лежат в /etc/init.d, а вовсе в /lib/svc/method. Соответственно, схема с линками устарела и надо регистрировать сервис посредством команд SMF (очень удобно, кстати. Всякие там upstart/startd рядом не валялись. И мониторинг состояния, и availability, и прочие вкусности давно реализованы. Но мы ж легких путей не ищем, да и то - решение, как я уже говорил, должно полежать в земле десяток лет, чтобы стухло хорошенько - как мясо для медведей - чтобы стать пригодным в пищу айтишникам. "Зрелое решение" - это то, которое давно сдохло либо приближается к оному. Но это лирика).

Господа DBA! Решение - написать свой собственный сервис автозапуска, причем можно сделать это гораздо лучше. Не бином Ньютона ведь - а пара-тройка борновских скриптов, один для управления и пара для установки и удаления автостарта.

Зато какая ляля - ставишь, допустим, очередную БД - и сразу - бенц! - скрипт выполнил, установил, reboot - и готово. И это насовсем. Не дай бог, сбойнул UPS в ваше отсутствие - не надо лететь сломя голову посреди ночи в пижаме на работу, дабы руками поднять необходимые службы.

Нет же, блин. "Мыши плакали, кололись, но продолжали есть кактус." (С)

За более, чем четырнадцать лет работы с Oracle на UNIX я видел всего пару попыток написать собственный кошерный сервис автоматического запуска. Одну из них - в зеркале.

Да, я убил достаточно много времени на написание и тестирование на поддерживаемых платформах. Но зато в дальнейшем мне не надо изгаляться при установке очередной системы, создавая линки и, с матами, редактированием оракловых нативных запускных скриптов и правкой oratab и другими заморочками.

Ну ленивый я, как всякий правоверный сисадмин. Мне влом даже такие типовые действия, как редактирование oratab и создание линков выполнять. Ко всему, моя основная платформа давно ушла вперед от rcX.d.

Я это делаю одной командой. install.sh. Все.

А для возвращения к мазохизму рукопашного запуска - remove.sh.

На мой взгляд, получилось весьма неплохое решение. "Лучше день потерять - потом за пять минут долететь".

Что, думаете, благодарное сообщество растащило с довольным урчанием по углам?

Как бы не так!

"Граната у тебя не той системы!" (С)

- Ах-ох, заголовки скриптов не по стандарту Fedora! (Чхал я на федору с ее самопальными стандартами, скрипты написаны по моим собственным стандартам, и основные методы start, stop, restart поддерживают. А вообще все это писалось для Solaris primary)
- Ах-ох, нету метода status у запускного скрипта! (эй, а вы в курсе, что у половины процессов Oracle нету pid-файла? И даже проверка процесса командой ps не гарантирует, что сервис жив? Там, если что, лог есть, в котором можно посмотреть статус запуска/останова, а в Solaris 10 для работающих сервисов есть команда svcs!)
- Ах-ох, зачем столько сложностей с этим.... как его... SMF? Просто создай линки и все! (Бином Ньютона - SMF. Штатная подсистема Solaris 10 и выше, если что)
- Ах-ох, не запускается CSS! (Ребята, а это ничего, что на всех платформах, включая Windows, есть штатная оракловая команда localconfig add, добавляющая необходимый сервис в автоматический запуск? Эксперты по RAC сертифицированные, блин! Кстати, да, ораклиный скрипт запуска ocss.bin ужасен. Не соответствует никаким "стандартам" линуска. Зато он кроссплатформенный. Ничего не напоминает?)
- Ах-ох, это ж целый сервис устанавливается! А зачем, когда можно линки создать итп. (А это ничего, что в Windows oradim тоже устанавливает сервисы - да еще и не один? В SMF это тоже называется "сервис", для остальных систем там за вас install.sh линки-то и создаст где надо. Ну а если хочется ручками запускать - так есть remove.sh, чисто удаляющий все следы автостарта - где проблема-то? И, кстати - это ничего, что CSS тоже устанавливается в вашу систему как сервис?)
- Ах-ох, зачем это вообще было писать, когда можно .... (далее по вкусу). (Зачем - написано в readme в первом абзаце, но об этом чуть ниже)

И - (барабанная дробь) - коммент номер один:

- ... Дальше я просто не стала читать (readme - примечание мое)

А я-то, дурак, считал, что хотя бы маны курить - это основополагающий навык админов. Мне, например, совсем не хотелось читать мануалы Оракла - они же огромные, да написаны та-аким английским, что улыбнешься. Ну, а если уж мы маны читать не осиливаем - то написать скрипт нам и вовсе не по зубам, куда там.

Заметьте, никто не попытался сказать "Эй, смотри - а я написал лучше!". Нифига подобного. Расшибутся в лепешку в поисках написанного кем-то по рекомендации неведомо кого на форуме, но потрудиться научиться писать скрипты самим - это ж надо мозг напрягать! Ну нах... Сказано было лишь - "А это уже написано и пофигу, что стремно - нас этот кактус устраивает".

Если бы это был единичный случай! Вы посмотрите по сторонам! Окошечники не умеют писать батники. Так называемые юниксоиды и линуксоиды в принципе не утруждают себя изучением скриптовых возможностей своих шеллов. В моей практике был феерический случай, когда для разовой обработки CSV-файла MSCE предложил написать программу на Visual Studio! И это при том, что в cmd.exe есть нативный цикл for с непосредственной обработкой полей CSV и достаточно прочитать хепл командой help for.

Жесть, не правда ли?

Господа аццкие мега одмины!

1. Учите матчасть тщательней. Следите за новостями из вашего собственного профессионального мира, в нем иногда происходят изменения. А не просто торчите в онлайновых игрищах и дурацких форумах в уверенности, что вы уже знаете все на светенеобходимое.
2. Выучите, наконец, хотя бы один скриптовый язык. Он позволит вам сэкономить ваше собственное рабочее и личное время. Как минимум, будете понимать написанное другими, нормальными админами.
3. Когда выучите скриптинг как следует - сможете не дурацки критиковать написанное не вами (фатальный недостаток, не правда ли?), а засучить рукава и написать лучше. Если уж на то пошло. А не жрать кактус, написанный когда-то недоучившимся студентом или - какой ужас! - не вами.

Компрене ву?

понедельник, 10 января 2011 г.

Насколько необходим directio в ZFS?

Файловые системы, не являющиеся ZFS -
не такие превосходные, как ZFS.


(фраза участника одного из

зарубежных профессиональных форумов)

Мне не раз приходилось слышать о том, что-де архитектура ZFS плохо подходит для Oracle с его собственным кэшированием, что было бы совсем хорошо, если бы можно было отключить кэширование ZFS подобно тому, как это делается для UFS при монтировании с опцией directio.

Directio в ZFS нет и не будет, вопрос необходимости такой опции мне лично предоставляется спорным, однако это тема несколько иной статьи.

Что до архитектуры, то большинство ФС являются кэширующими, и если кэш ФС вам реально мешает - всегда есть два выхода. Использование raw devices (в новых версиях Оракла прямо не поддерживаемых) и ASM (сиречь OCFS). Это тоже тема другой статьи, как и необходимость использования именно некэширующих файловых систем и очень спорная тема.

Давайте проведем небольшой эксперимент и выясним, можно ли отключить кэширование ZFS и каким образом. А также - как это скажется на поведении БД.

Для начала небольшая вводная по архитектуре текущей версии ZFS.

ARC по своей природе устроен в виде двухуровневой структуры. Собственно ARC в памяти (L1), и кэш второго уровня (L2) на диске, управляемые, в свою очередь, параметрами primarycache и secondarycache.

Поскольку ZFS кэширующая по своей природе, отключить ARC в оперативной памяти полностью не удастся:

*Default arc min is 12% of memory (see CR 6855793)
*Set zfs_arc_min if applications have a chance to consume more than this.
*zfs_arc_min should be at least 64MB and not more than arc_c_max (zfs_arc_max).

что можно легко подтвердить попыткой зануления параметра zfs_arc_max в /etc/system (set zfs:zfs_arc_max=0). То есть, если установить этот параметр равным нулю, а потом посмотреть на значения величин кэша, можно легко убедиться (например, при помощи скрипта arc_summary.pl), что нулевое значение игнорируется полностью.

Однако, при желании, можно почти полностью отключить использование кэша ARC в памяти параметром primarycache=none. А также практически полностью исключить влияние кэша второго уровня на БД, установив параметр secondarycache=none. Что в принципе эквивалентно монтированию в режиме directio.

Резонный вопрос, даст ли это хороший выигрыш.

В действительности - совершенно не факт.

Апологеты использования raw devices почему-то наивно считают, что в СУБД-приложениях получат хороший выигрыш в производительности. Это не так. Максимальный выигрыш, который в принципе удается получить при размещении БД на сырых устройствах, составляет 7-10%. При этом на свою голову вы получаете неслабые проблемы с администрированием (например, выполнение холодных бэкапов совсем не тривиально для сырых устройств и уж точно не быстро). Более того, попытки таким образом решить проблемы с узкими местами систем хранения и, тем более, с кривизной запросов, обречены на неудачу. И, более того, практические опыты с directio на UFS показывают, как правило, падение скорости обменных операций БД.

Осталось посмотреть на кэш L1/L2 ZFS и его влияние на работу БД. Давайте проведем небольшой эксперимент.

Сначала посмотрим текущие значения параметров кэша L1/L2 по умолчанию для пула, на котором у нас установлена БД:

root @ pegasus / # zfs get all data
...
data primarycache all default
data secondarycache all default
...

Перезапустим базу для того, чтобы кэш БД был холодным и несколько раз выполним простенький запрос к маленькой табличке:

oracle @ pegasus ~ $ sqlplus scott/tiger

SQL*Plus: Release 10.2.0.5.0 - Production on Пн Янв 10 15:14:56 2011

Copyright (c) 1982, 2010, Oracle. All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, Oracle Label Security, Data Mining and Real Application Testing options

SQL> set timing on
SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.63

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.02

SQL> set timing off

Запомним время выполнения первого запроса (до кэширования таблицы Ораклом).

Посмотрим на статистику ARC:

root @ pegasus / # arc_summary.pl
System Memory:
Physical RAM: 1759 MB
Free Memory : 551 MB
LotsFree: 27 MB

ZFS Tunables (/etc/system):

ARC Size:
Current Size: 462 MB (arcsize)
Target Size (Adaptive): 1319 MB (c)
Min Size (Hard Limit): 164 MB (zfs_arc_min)
Max Size (Hard Limit): 1319 MB (zfs_arc_max)

ARC Size Breakdown:
Most Recently Used Cache Size: 50% 659 MB (p)
Most Frequently Used Cache Size: 50% 659 MB (c-p)

ARC Efficency:
Cache Access Total: 140823
Cache Hit Ratio: 85% 119956 [Defined State for buffer]
Cache Miss Ratio: 14% 20867 [Undefined State for Buffer]
REAL Hit Ratio: 80% 112670 [MRU/MFU Hits Only]

Data Demand Efficiency: 91%
Data Prefetch Efficiency: 22%

CACHE HITS BY CACHE LIST:
Anon: 6% 7226 [ New Customer, First Cache Hit ]
Most Recently Used: 23% 28020 (mru) [ Return Customer ]
Most Frequently Used: 70% 84650 (mfu) [ Frequent Customer ]
Most Recently Used Ghost: 0% 19 (mru_ghost) [ Return Customer Evicted, Now Back ]
Most Frequently Used Ghost: 0% 41 (mfu_ghost) [ Frequent Customer Evicted, Now Back ]
CACHE HITS BY DATA TYPE:
Demand Data: 67% 81176
Prefetch Data: 2% 2641
Demand Metadata: 25% 30995
Prefetch Metadata: 4% 5144
CACHE MISSES BY DATA TYPE:
Demand Data: 38% 7959
Prefetch Data: 43% 9108
Demand Metadata: 10% 2149
Prefetch Metadata: 7% 1651
---------------------------------------------

Запретим кэшировать все на первом и втором уровне:

root @ pegasus / # zfs set primarycache=none data
root @ pegasus / # zfs set secondarycache=none data
root @ pegasus / # zfs get primarycache data
NAME PROPERTY VALUE SOURCE
data primarycache none local
root @ pegasus / # zfs get secondarycache data
NAME PROPERTY VALUE SOURCE
data secondarycache none local

Перезапустим систему для чистоты эксперимента и выполним несколько раз тот же самый запрос к той же самой таблице:

oracle @ pegasus ~ $ sqlplus scott/tiger

SQL*Plus: Release 10.2.0.5.0 - Production on Пн Янв 10 15:27:49 2011

Copyright (c) 1982, 2010, Oracle. All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, Oracle Label Security, Data Mining and Real Application Testing options

SQL> set timing on
SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.27

SQL> /

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.12

SQL> set timing off

Обратим внимание на две вещи. Первая - время выполнения первого запроса (напоминаю - до кэширования таблицы Ораклом) уменьшилось в два раза. Последующие запросы, как показывают повторные выполнения, занимают несколько больше времени по причине того, что мы отключили кэширование целиком на пуле хранения, и этот эффект прямо не связан со скоростью чтения ораклом блоков (как мы покажем позже).

Проверим статистику ARC:

root @ pegasus / # arc_summary.pl
System Memory:
Physical RAM: 1759 MB
Free Memory : 787 MB
LotsFree: 27 MB

ZFS Tunables (/etc/system):

ARC Size:
Current Size: 210 MB (arcsize)
Target Size (Adaptive): 1319 MB (c)
Min Size (Hard Limit): 164 MB (zfs_arc_min)
Max Size (Hard Limit): 1319 MB (zfs_arc_max)

ARC Size Breakdown:
Most Recently Used Cache Size: 50% 659 MB (p)
Most Frequently Used Cache Size: 50% 659 MB (c-p)

ARC Efficency:
Cache Access Total: 180400
Cache Hit Ratio: 44% 80577 [Defined State for buffer]
Cache Miss Ratio: 55% 99823 [Undefined State for Buffer]
REAL Hit Ratio: 42% 76312 [MRU/MFU Hits Only]

Data Demand Efficiency: 57%
Data Prefetch Efficiency: 19%

CACHE HITS BY CACHE LIST:
Anon: --% Counter Rolled.
Most Recently Used: 13% 11140 (mru) [ Return Customer ]
Most Frequently Used: 80% 65172 (mfu) [ Frequent Customer ]
Most Recently Used Ghost: 11% 9001 (mru_ghost) [ Return Customer Evicted, Now Back ]
Most Frequently Used Ghost: 94% 75979 (mfu_ghost) [ Frequent Customer Evicted, Now Back ]
CACHE HITS BY DATA TYPE:
Demand Data: 62% 50721
Prefetch Data: 0% 107
Demand Metadata: 31% 25556
Prefetch Metadata: 5% 4193
CACHE MISSES BY DATA TYPE:
Demand Data: 38% 38254
Prefetch Data: 0% 433
Demand Metadata: 59% 59630
Prefetch Metadata: 1% 1506
---------------------------------------------

Обратите внимание, что, хотя коэффициент кэш-попаданий и уменьшился почти вдвое(REAL Hit Ratio), время выполнения первого запроса при холодном кэше базы все же стало вдвое лучше, чем при включенном кэшировании L1/L2 ZFS.

С чем связано такое ухудшение скорости при повторном выполнении запросов к уже кэшированной таблице? Навскидку объяснения у меня нет, есть предположение, связанное с тем, что мы отключили кэширование на всем пуле, где находится и БД и софт Oracle.

Замечание. Ухудшение кэш-попаданий файловой системы имеет очевидную причину - мы запретили кэширование данных и получаем их в кэш БД практически непосредственно, при этом мы не кэшируем также другие части БД и собственно установленное ПО, что при повторных обращениях ухудшает статистику кэша ФС.

Так как пул разбит на датасеты, установим атрибуты отключения кэша L1/L2 только на тех датасетах, на которых находится БД и повторим эксперимент (глобально на всем сторидж-пуле включим кэширование L1/L2 обратно):

root @ pegasus / # zfs list
NAME USED AVAIL REFER MOUNTPOINT
data 11.0G 8.54G 36K /data
data/OraHome1 3.37G 8.54G 3.37G /data/OraHome1
data/OraHome2 716M 8.54G 716M /data/OraHome2
data/apex 785M 8.54G 785M /data/apex
data/oradata 2.50G 8.54G 1.98G /data/oradata
data/oradata/flash 21K 8.54G 21K /data/oradata/flash
data/oradata/plsql_libs 219M 8.54G 219M /data/oradata/plsql_libs
data/oradata/redo1 157M 8.54G 157M /data/oradata/redo1
data/oradata/redo2 157M 8.54G 157M /data/oradata/redo2

root @ pegasus / # zfs set primarycache=none data/oradata/redo1
root @ pegasus / # zfs set primarycache=none data/oradata/redo2
root @ pegasus / # zfs set primarycache=none data/oradata/flash
root @ pegasus / # zfs set primarycache=none data/oradata
root @ pegasus / # zfs set primarycache=all data/oradata/plsql_libs
root @ pegasus / # zfs set secondarycache=none data/oradata/redo1
root @ pegasus / # zfs set secondarycache=none data/oradata/redo2
root @ pegasus / # zfs set secondarycache=none data/oradata/flash
root @ pegasus / # zfs set secondarycache=none data/oradata
root @ pegasus / # zfs set secondarycache=all data/oradata/plsql_libs

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.23
SQL> /

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.01
SQL> /

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7369 SMITH CLERK 7902 17.12.80 800
20

7499 ALLEN SALESMAN 7698 20.02.81 1600 300
30

7521 WARD SALESMAN 7698 22.02.81 1250 500
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02.04.81 2975
20

7654 MARTIN SALESMAN 7698 28.09.81 1250 1400
30

7698 BLAKE MANAGER 7839 01.05.81 2850
30


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09.06.81 2450
10

7788 SCOTT ANALYST 7566 09.12.82 3000
20

7839 KING PRESIDENT 17.11.81 5000
10


EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08.09.81 1500 0
30

7876 ADAMS CLERK 7788 12.01.83 1100
20


11 rows selected.

Elapsed: 00:00:00.02

Кажется, наше предположение оказалось правильным. Мы получили то, что хотели - сокращение времени выполнения первого запроса вдвое и выполнение последующих запросов со скоростью их выполнения на полностью закэшированном пуле.

Проверим статистику ARC:

root @ pegasus / # arc_summary.pl
System Memory:
Physical RAM: 1759 MB
Free Memory : 796 MB
LotsFree: 27 MB

ZFS Tunables (/etc/system):

ARC Size:
Current Size: 257 MB (arcsize)
Target Size (Adaptive): 1319 MB (c)
Min Size (Hard Limit): 164 MB (zfs_arc_min)
Max Size (Hard Limit): 1319 MB (zfs_arc_max)

ARC Size Breakdown:
Most Recently Used Cache Size: 50% 659 MB (p)
Most Frequently Used Cache Size: 50% 659 MB (c-p)

ARC Efficency:
Cache Access Total: 127803
Cache Hit Ratio: 83% 106971 [Defined State for buffer]
Cache Miss Ratio: 16% 20832 [Undefined State for Buffer]
REAL Hit Ratio: 80% 102670 [MRU/MFU Hits Only]

Data Demand Efficiency: 90%
Data Prefetch Efficiency: 37%

CACHE HITS BY CACHE LIST:
Anon: --% Counter Rolled.
Most Recently Used: 20% 22190 (mru) [ Return Customer ]
Most Frequently Used: 75% 80480 (mfu) [ Frequent Customer ]
Most Recently Used Ghost: 0% 731 (mru_ghost) [ Return Customer Evicted, Now Back ]
Most Frequently Used Ghost: 6% 6684 (mfu_ghost) [ Frequent Customer Evicted, Now Back ]
CACHE HITS BY DATA TYPE:
Demand Data: 72% 77064
Prefetch Data: 1% 1153
Demand Metadata: 23% 25247
Prefetch Metadata: 3% 3507
CACHE MISSES BY DATA TYPE:
Demand Data: 40% 8473
Prefetch Data: 9% 1926
Demand Metadata: 43% 9024
Prefetch Metadata: 6% 1409
---------------------------------------------

Как видите, статистика вернулась почти к своему первоначальному виду, при заметном сокращении времени чтения таблицы в холодный кэш базы данных.

Итак, что мы выяснили? Кэш L1/L2 в ZFS для баз данных Оракла в нашем случае действительно реально не требуется. И отключается кэширование без перестроения файловой системы парой команд. Если только - обратите внимание! - вам не нужно постоянно дергать статические файлы с диска - бинарники или библиотеки, файловые компоненты веб-фронта итп. Датасет с такими данными лучше оставить с параметрами кэша L1/L2 по умолчанию, что мы и сделали (нативно скомпилированные объектные библиотеки PL/SQL) выше.

Прошу заметить, что отключение кэша ARC L1, в отличие от кэширования L2, может оказаться вредным конкретно для вашей БД. Мы провели эксперимент с крошечной таблицей и запросом, выполняющим очевидный полный скан. В случае повторяющихся диапазонных сканов в запросах с соединением nested loops и при использовании индексов отключение кэша L1 может реально привести к снижению производительности.

Вывод следующий. Дисковый кэш L2 для базы достаточно часто может оказаться избыточным. Кэш L1 - зависит от характера базы. В более общем случае лично я бы не отключал кэширование первого уровня полностью, а кэшировал бы только метаданные (для сохранения скорости доступа к файлам) установкой параметра primarycache=metadata.

Остается один вопрос - с какой целью было сделано дисковое кэширование второго уровня?

Все очень просто. ZFS - файловая система общего назначения (совмещенная с volume manager, но это и так очевидно), в частности, предназначенная в числе прочего для создания файловых хранилищ. Кэш L2 может, конечно, располагаться на тех же устройствах, что и основной пул хранения, но в первую очередь это функциональность файловых хранилищ с гибридной структурой. Например, основной массив данных хранится на дешевых дисках JBOD с интерфейсами SATA, а кэш L2 и ZIL вынесены на отдельные быстродействующие устройства SSD либо SAS при создании пула хранения. Соответственно, в кэш L2 можно выдергивать либо метаданные, либо все, обеспечивая желаемое распределение операций ввода-вывода по устройствам.

Поскольку в нашем примере для базы данных эта функциональность избыточна, мы ее отключили и получили вполне предсказуемый результат, так как блоки базы не надо лишний раз перекладывать из кэша в кэш, один из которых является дисковым.

Что вовсе не означает - заметьте! - что ZFS архитектурно не совместима с базами данных. А всего лишь говорит о том, что данная файловая система способна работать с почти любыми классами приложений, под которые ее всего лишь необходимо настроить.

Остается лишь заметить, что параметры ZFS "из коробки" являются усредненными, но отнюдь не идеальными для всех без исключения приложений. Что, в общем-то, самоочевидно всем, кроме дилетантов, желающих все и сразу и непременно "волшебную пулю".

К чести ZFS надо заметить, что она прекрасно настраивается, позволяя получить почти любой желаемый результат и единственный, на мой взгляд, недостаток ее реализации в Solaris - это невозможность (в текущей версии) выбрать размер recordsize для корневого пула при установке системы.

PS. Оставим пока за кадром, как умудряются некоторые рукосуидеятели испохабить ZFS до такой степени, чтобы потом склонять ее за плохую производительность под БД. И эта глупая байка так и гуляет по форумам и пустым головам анонимных "аналитиков". У меня всегда появляется в этом случае вопрос - что я делаю не так? Я постараюсь ответить на этот вопрос в следующих статьях.

суббота, 8 января 2011 г.

Почему Linux не является платформой

Совместимость важнее производительности.
(Древняя IT-шная максима)

В последнее время я неоднократно сталкивался в Интернете с термином "Платформа Linux". Меня, как практика, очень коробит этот оксюморон. Причем я не одинок в своем мнении. Недавно я встретил аналогичное мнение на одном очень популярном IT-форуме. К сожалению, это мнение не просуществовало долго, так как было высказано в достаточно резкой форме.

Я хочу попытаться убедить тех, кто способен слышать, почему Linux не является платформой. Прежде всего тех, кто принимает решения о выборе этой самой платформы.

Итак, как мы видим из Вики, четкого определения термина "платформа" мы не имеем по сей день. Давайте попытаемся сформулировать, что же мы все-таки понимаем под понятием "платформа" с точки зрения практиков.

Есть аппаратная платформа - совокупность архитектуры центрального процессора, шин, и некоего минимального набора периферии, обеспечивающий выполнение определенных операционных систем и прикладных программ. Например, x86 - это аппаратная платформа.

Есть операционная система, которая выполняется на аппаратной платформе и обеспечивает единую унифицированную среду для выполнения прикладных программ и взаимодействия пользователя с аппаратной платформой (выделено мной). Операционная система представляет собой комбинацию ядра и operational environment, или userland. Помимо этого, ОС имеет оболочку (оболочки), файловые системы, сетевой интерфейс, структуру директорий.

Какими чертами, с точки зрения директора IT, должна обладать платформа, дабы считаться таковой?

  1. Платформа должна обладать достаточно длительным жизненным циклом (порядка десяти лет) и обеспечивать в течение этого периода возможность выполнения большинства однажды написанных прикладных программ.
  2. Платформа должна быть стабильной, не меняться непредсказуемым образом в произвольные промежутки времени без веских причин.
  3. Платформа должна иметь единый API (для сохранения архитектурного единства приложений и единых подходов к разработке) и унифицированный ABI (в случае операционных систем для обеспечения выполнения единожды написанных и скомпилированных приложений без необходимости их перекомпиляции).
  4. Платформа должна иметь единый административный и прикладной интерфейс. А именно, использовать конечное количество оболочек, обеспечивать единое пространство управления процессами и системами, иметь единый интерфейс установки прикладного ПО и пакетов программ, иметь единый интерфейс управления обновлениями. Кроме этого, иметь единую структуру директорий, с одинаковым месторасположением основных компонентов юзерленда и системных компонентов.
  5. Платформа имеет достаточно большое сообщество разработчиков и поставщиков прикладных программ, эксплуатируемых на ней.
Все это требуется для того, чтобы обеспечить возможность выполнять однократно написанную прикладную программу или систему на возможно большем количестве вычислительных систем (иметь большую инсталляционню базу) без необходимости рекомпиляции, а также минимизировать TCO (совокупную стоимость владения) за счет уменьшения затрат на поддержку и увеличения жизненного цикла программно-аппаратного комплекса.

Замечание. Совсем не каждая операционная система является платформой. KolibriOS - операционная система. Но она - не платформа.

Ранее платформой в общем смысле этого слова неформально считалась совокупность аппаратной платформы и операционной системы.

Это определение остается верным по сей день, однако мы его несколько дополним. Платформой так же является достаточно распространенная единая среда выполнения приложений. Я подчеркиваю - единая. С единым пользовательским и прикладным интерфейсом, единой структурой директорий, пакетов, библиотек, едиными подходами к управлению и администрированию.

В некоторых случаях платформами с натяжкой можно считать различные операционные среды, удовлетворяющие большинству требований к платформам. Например, Java - может считаться платформой, поскольку является средой для выполнения прикладных программ. Такой платформой может считаться даже Perl.

Говоря простым языком - от платформы требуется стабильность, единство и возможность выполнять возможно большее количество прикладных программ. А также возможность, изучив систему один раз, использовать постоянные и воспроизводимые подходы на всех последующих версиях платформы без необходимости переобучения. Использовать, непример, единые скриптовые комплексы на большинстве версий данной платформы. Находить прикладные программы и их данные в одних и тех же местах. И так далее.

Я повторяю, все это означает, что мы рассматриваем платформу с точки зрения департамента IT.

Говоря простым языком, если я планирую построение крупной инфраструктуры критичных систем, работающих в режиме 24х7х365, и при этом планирую минимизировать затраты, (что очень естественно для бизнеса, не правда ли?) я буду выбирать платформу, которая позволит мне, установив оборудование и ОС один раз, с минимальными затратами обновлять и обслуживать их с минимальным простоем, без необходимости обновлять прикладные системы, на протяжении возможно большего промежутка времени. Что, в частности, подразумевает, что, раз обучив системных администраторов, мне не придется потом ежегодно тратиться на их переобучение в связи с кардинальными изменениями платформы. Кроме этого, для сокращения TCO мне желательно для эксплуатации систем использовать минимально квалифицированный персонал уровня операторов, а не дорогостоящих гениев ядерного хака.

Ну и такое простое соображение. Полностью переустановить домашний писюк - это вовсе не то же самое, что и переустановка нескольких тысяч серверов в датацентре, правда?

Однако, несмотря на максиму, вынесенную в заголовок, и которая коротко обобщает все то, что мы только что сформулировали, с единством в компьютерном мире очень туго. Даже, несмотря на титанические усилия, стандарт POSIX обязательным так и не стал. Я сколько себя в компьютерных системах помню, его пытаються разработать и насадить. Безуспешно.

Таким образом, платформами мы можем считать - с точки зрения enterprise и с некоторыми - весьма существенными - натяжками:

  • Большинство UNIX-систем
  • Несмотря на все недостатки и кривизну - Wintel (Windows + Intel). Большая часть приложений, написанных для Win32 более десяти лет назад, без использования костылей и грязных хаков, посейчас исполняется на современных версиях
  • Java
Обратите внимание, что, для того, чтобы стать платформой, операционный среда должна быть стабильной, по-возможности непротиворечивой, развиваться эволюционно, в рамках единой стратегии и, в подавляющем большинстве случаев, в рамках авторитарного управления.

Потому что, как директору IT, лично мне неприемлема ситуация, когда, после обновления ОС, перестает работать большинство моих прикладных программ, за которые плачены деньги или на которые потрачено много времени и усилий и которые использует достаточно большое количество пользователей. Или если требуется обновлять приложения. Переустанавливать их. Так же, как недопустима ситуация необходимости перекомпиляции большинства приложений для обеспечения совместимости с новой версией операционной среды или необходимость переучивания обслуживающего персонала в связи с этим же. Постоянно мутирующая операционная среда платформой не является и являться не может по определению.

Очень хорошо (хотя и достаточно грубо) выразился один мой коллега: "На домашнем десктопе вы можете хоть дрочить вприсядку. На предприятии я хочу один раз установить сервера и выкинуть их через десять лет по причине физического износа оборудования. После того, как они многократно окупятся".

Замечание. Я с ним полностью согласен. Перманентно красноглазить вы можете дома, собирая и пересобирая систему just for fun и наслаждаясь своей немеренной крутизной в сборке ядер и юзерленда, допиливая и перепиливая систему как вам взбрендится, добиваясь того, чтобы какой-то софт работал на вашей персональной платформочке. Причем лично мне даже это глубоко претит. Я не сторонник мастурбационного компьютинга. Я не хочу заниматься со своей ОС на десктопе, ковыряя ее неделями. Я хочу один раз ее поставить, настроить и забыть о ней на несколько лет, пока не придет пора вынужденной ее смены либо оборудование придется выбрасывать.

Говоря простым языком, для платформы недопустимы подходы "Однажды лебедь раком щуку" и "Кому-то нравится поп, кому-то попадья, а кому-то свиной хрящик".

Что мы имеем в случае Linux?

А имеем мы полную доступность всех исходников для каждого и физическую возможность клепать сколько угодно дистрибутивов.

Что на деле означает полную анархию. "Мама-анархия, папа-стакан портвейна".

Сотни "платформочек". По большей части несовместимых на уровне ABI, библиотек, ядер, пакетов и системы патчей. Различных в такой степени, что фактически являющихся несовместимыми друг с другом на большинстве уровней. Инсталляционная база каждой составляет от нескольких сот до нескольких тысяч систем в максимуме. Сами любители анархии постоянно сталкиваются с ситуацией, когда приложение либо несовместимо на уровне пакетного менеджера (что еще хорошо) либо на уровне ABI и просто физически не работает на их платформочке, будучи скомпилированной на другой.

Пример? Пожалуйста - вот он. Обратите внимание - по одной сборке для Windows и Solaris, одна сборка для MacOS и два десятка сборок для Linux.

О чем это говорит? О том, что целевые Linux-дистрибутивы несовместимы между собой. А здесь ведь далеко не все дистры представлены! А лишь самые известные и основные!

И ладно бы, нежизнеспособное само сдохло. И осталась бы пара-тройка устоявшихся платформ, централизованно, предсказуемо и авторитарно развиваемых и поддерживаемых, стандартизированных. Так нет же!

Каждую неделю в среднем рожают один новый дистрибутив. Каждый лепит его по-своему. Создавая сотни несовместимых между собой платформочек. В какой-то момент разработчикам и мэнтайнерам прикладного софта ведь настоиграет собирать и поддерживать десятки и сотни вариантов своих программ. О, вот вам исходники - занимайтесь ими сами.

Хороший подход. Приемлемый для красноглазого мастурбатора дома. И категорически неприемлемый на предприятии.

То, что совместимость идет к черту - это одна сторона медали. Со второй красноглазые еще просто не познакомились. Вымышленный диалог в отделе кадров:

- Здравствуйте, вы системный администратор?
- Да, я системный администратор Linux.
- С каким дистрибутивом вы работаете?
- С дистрибутивом ЛунныйСвет.
- Мы используем КраснуюШапку.
- Простите, я ее не знаю. Даже никогда о ней не слышал.
- Спасибо, вы нам не подходите, до свидания.

Если говорить о безопасности, то дело вообще швах.

Одно дело, когда платформа, оставаясь в большей части неизменной, годами вылизывается в рамках своего жизненного цикла с точки зрения безопасности. В какой-то момент она и становится достаточно безопасной. Но когда платформа меняется постоянно, причем никто не обременяет себя ни secure by design, ни аудитами кода, ни даже сколько-нибудь регулярными обновлениями безопасности - на кой ляд мне такая платформа? Более того - кардинальные изменения вносятся по принципу "шоб було", а создатель дистрибутива обычно в безопасности разбирается как свинья в апельсинах.

Не раз и не два были ситуации, когда публикуется какой-нибудь новый эксплоит. Все пингвинятники дружно начинают его пробовать. "Ой, у меня сработал, ой, и у меня, и у меня тоже, а у меня нет, у меня БСД, ха-ха-ха, так вам и надо!" Далее - по квалификации, либо патчат сами, либо ждут патча, либо, плача и колясь, продолжают есть кактус.

Я не говорю, что закрытый код лучше. Но, например, в случае платформ, централизованно выпускаются обновления безопасности, минимум раз в квартал. Что позволяет достаточно спокойно эксплуатировать системы, находящиеся в публичном доступе.

Швобода, говорите? Бери исходники и пили их сам? Как однажды выразился один мой хороший знакомый - "Банк - это не софтверхаус". Цель департамента IT - не интеллектуальная мастурбация с платформой, а эксплуатация прикладных систем и обеспечение потребностей бизнеса.

Оставим в покое параноидальные мысли об открытых исходниках и закладках. Те, кого это реально беспокоит, могут нанять профессиональную команду и за несколько лет создать собственную ОС с нуля. Если не слабо. И если это реально необходимо.

Да, лицензии и поддержка платформ стоят денег. Но десяток красноглазых прыщебхомяков, пилящих мою платформу, за жрат работать не будут и вряд ли обойдутся дешевле, чем покупка поддержки. Помимо того, что я делаю бизнес заложником этих самых красноглазых, которые отнюдь не всегда отличаются здравомыслием.

С точки зрения все того же директора IT есть три варианта.
  1. Послать Linux к чертовой матери и использовать платформу.
  2. Выбрать один из считанных единиц дистрибутивов, находящийся в одних, достаточно богатых, авторитарных и сильных руках и использовать его, купив официальную поддержку. С натяжкой, такие дистры можно пересчитать по пальцам одной руки. Это будет каким-то подобием платформы.
  3. Взять в свои руки полный набор исходников, нанять красноглазых хомяков, зажать их в ежовые рукавицы и создать собственный закрытый дистр для собственных надобностей. Поддерживая, развивая и переписывая его собственными силами. И послав в глубокую задницу сообщество с его анархическим подходом. Такой подход по зубам весьма немногим - Google, например. У кого квалифицированных кадров и денег куры не клюют. Будет приватная платформа ПредприятиеLinux.
На мой личный взгляд, самый лучший вариант - первый. И не надо мне расписывать преимущества дистрибутива ЛунныйСвет. В сортах дерьма не разбираюсь.

PS. Соображения, что-де Linux нынче мэйнстрим, меня лично как-то не убеждают. Мэйнстрим - не синоним платформы. Обратите внимание - в основном, к Linux Foundation присоединяются хардверные вендоры, которым нужны дармовые драйверы для обеспечения продаж их железа. Драйверы - они, знаете ли, платформу не определяют. А какая разница, купят железку окошечники или красноглазые пингвинятники? Раз вас так много. Деньги - они не пахнут.

среда, 5 января 2011 г.

О ценности персональных данных

Не болтай.
(фраза с плаката-агитки советского периода)

Я не раз и не два слышал от людей такую фразу - "А что плохого, если мои персональные данные кто-то получит? Мне скрывать нечего, я человек честный". (выделено мной)

Удивительно, но большинство людей физически не считают собственные персональные данные чем-то ценным. А некоторые даже чужие персональные данные не ценят и всегда радостно готовы поделиться ими с посторонними (как показывает печальный жизненный опыт. Очень жаль, что зачастую на чужой роток не накинешь платок.)

Я хочу попробовать развеять это печальное заблуждение.

Нет, я не буду приводить устрашающую статистику киберпреступлений.

И не буду цитировать дурацкие федеральные и прочие законы о персональных данных (которые, на мой взгляд, сродни попыткам закрыть конюшню после того, как оттуда все уже сперли. На мой взгляд, снговские законы о персональных данных во-первых, близко не валялись рядом с западными, во-вторых, у нас они работать не будут а вот поводом для кормежки государственной номенклатуры станут еще как, а в-третьих, они так и не смогут пречесь организованных утечек баз с персональными данными наружу, как это было всегда. Цена вопроса очень уж стоящая, чтобы можно было рискнуть нарушить эти самые законы).

Я попытаюсь на пальцах объяснить господам несознательным гражданам важность защиты персональных данных.

Итак, пример раз.

Представьте себе ситуацию, когда каждый месяц какое-нибудь печатное издание публикует реестры персональных данных граждан - адреса, телефоны, состав семей, места работы, уровень доходов.

А что, вам же скрывать-то нечего, вы же люди честные. Как вы думаете, кто будет читателями этого издания и что будет с гражданами, занимающими верх списка по уровням доходов?

Практически это та самая информация, которую люди размещают в социальных сетях - прямо или косвенно, в различных степенях раскрытия и детализации. Но в любом случае эту информацию легко получить целенаправленным поиском, причем, поддающимся автоматизации. И, заметьте - вы сами ее размещаете. Зачастую дополняя пикантными подробностями, типа экзотических хобби и сексуальной ориентации.

Нечего скрывать, говорите?

Как насчет того, что называется identity theft - кражей идентичности? Вы не знаете, что это такое?

Приведу тривиальный пример. Обладая достаточным количеством персональных данных, можно, например, от имени человека получить кредит. А потом, к ничего не подозревающей жертве, придут коллекторы - очень неприятные личности, выбивающие долги для кредиторов - на основе все той же общедоступной персональной информации, размещенной в открытых сетях. Силовики и коллекторы уже оценили удоства интернета. А наивные (чтобы не сказать - беспредельно глупые) должники и правонарушители - они же социализированные животные, без общения ни дня не проживут - вот они, как на ладони, в контакте, в одноклассниках, и так далее.

Другое фундаментальное свойство совокупности персональных данных называется у безопасников non repudiation. В переводе на русский - неотрекаемость.

Очень распространенное в обычной жизни свойство.

Говоря простым языком, если кто-то ведет себя как Вася Пупкин, выглядит как Вася Пупкин, и знает то, что должен знать Васей Пупкиным - то все сделанное им считается сделанным Васей Пупкиным.

Или, если у вас украли кредитку, а вы не успели вовремя об этом заявить, то все транзакции, сделанные с нее в этот период, считаются произведенными владельцем карты.

Это как раз то, что я рассматривал в предыдущем примере. Доказать коллекторам, что кредит брали не вы - будет очень сложно. И это лишь один из примеров противоправного использования персональных данных.

Пример два.

Список контактов в телефонной книге мобильного телефона - персональные данные или нет? Безусловно, персональные.

Дорогие честные мужчины, представьте себе, что ваш список контактов с мобильного телефона целиком передали вашим женам. И жены жаждут получить ваши развернутые комментарии по каждой позиции. Почему для якобы сотрудницы в контактах приведен домашний телефон. Ну и так далее.

Говорите, скрывать все равно нечего? Вы периодически жене зачитываете свой список контактов с комментариями? "Так, и глухого тоже в котел!" (С) что означает, что я вам не верю.

Пример три.

У вас угнали аську. Ну вот так, пароль вы выбрали слабый. Сменили пароль и либо вымогают у вас деньги за возврат, угрожая начать рассылать от вашего имени вашим контактам порочащие вас лично сообщения, либо просто спамят ваш контакт-лист. Благо, у мессенджеров контакт-листы хранятся на сервере, который вы физически не контролируете. Это, кстати, общая проблема IM-систем. Контакты в идеале должны храниться на клиенте, по моему личному мнению Но, они хранятся на сервере. Во-первых, надежней - там их резервируют, во-вторых, удобно - с какой бы машины не зашел, нужен только логин и пароль - а все контакты автоматически грузятся с сервера. Только вот пароли выбирать хорошие пользователи так и не научились. Итог закономерен и вполне печален.

Контрпример.

Я просто удивляюсь, как много желающих сломать почтовый аккаунт своей подружки на mail.ru. Судя по запросам в гугле и по вопросам ко мне лично, желающие не переводятся. Их просто мечут как икру. Буквально. Чем и пользуются те, кто якобы ломает почтовые ящики за деньги, но это уже совсем другая история.

А это ничего, что содержимое почтового ящика, в общем-то, тоже сугубо персональная информация? А зачем тогда там пароли, нам же скрывать-то, в общем, нечего, мы честные люди?! Не исключая ситуации, описанной в предыдущем примере.

Я сознательно оставляю за скобками тот факт, что чужие письма читать в высшей степени непорядочно, а еще более непорядочно писать от имени другого человека. Речь в данном случае совершенно о других вещах - а именно, о степени открытости персональных данных - собственных и чужих.

Я клоню к тому, что те из вас, которые настаивают на том, что скрывать им нечего, на самом деле сильно лукавят. Или им просто не причиняли реальный вред, используя их данные. До поры до времени. И в действительности вы совсем не готовы вести полностью открытый образ жизни. Потому что такой образ жизни вести, в общем, можно. Если уйти в скит в тайге. Как только у человека появляются иные интересы, кроме удовлетворения самых простейших потребностей - появляется то, что следует хранить в тайне.

Другая сторона медали - если даже вы сами не очень склонны раскидываться своими персональными данными, то это вполне могут сделать за вас. Тривиальный пример - соседка рассказывает свои наблюдения и домыслы о вашей жизни третьим лицам. Это происходит сплошь и рядом и никакими законами предотвратить это нельзя. На чужой роток не накинешь платок. Ни по каким федеральным законам нельзя привлечь таких , с позволения сказать, доброжелателей. А ущерб причиняется весьма реальный. Выдать вашу персональную информацию могут буквально кому угодно.

Что можно с этим сделать? Практически ничего, это неизбежное зло, проистекающее из ментальности. ОБС - такой же источник информации, как и интернет. Почему ментальности - потому что уважение к персональным данным - своим и чужим - вытекает из уважения к прайвиси. Причем такое понятие - прайвиси - в ментальности народов СНГ отсутствует как класс. И на западе-то, честно говоря, оно есть не везде - наличие паппараци и интерес к чужой частной жизни присутствует.

Но вернемся к нашему интернету.

Даже если вы - парень с башкой, и не размещаете ваших данных в социальных сетях, это вполне могут сделать за вас. Во-первых, отсутствие чего-либо в полной картине может быть таким же красноречивым, как и присутствие. И для хорошего аналитика не составит труда выяснить, что в этих данных вот в этом месте должен быть Вася Пупкин. Во-вторых, многие недалекие личности могут физически не отдавать отчета, что они могут, вместе со свими данными, затолкать в социалку данные людей (даже минимальные), которые бы хотели свою прайвиси сохранить. Подобные массивы структурированных персональных данных и связей в открытом доступе дорогого стоят. И используются по прямому назначению - для добычи информации.

Вы впечатлились и спешите убрать свою персональную информацию?

Поздно, дорогие мои.

Во-первых, есть такая штука, как эффект Стрейзанд.

Ну хорошо, вы не настолько популярны и вам он грозит в меньшей степени (хотя это еще вопрос).

Но во-вторых, хочу напомнить (а некоторым - сообщить впервые) о существовании Internet Archive Wayback Machine.

Это большой черный ящик (в прямом смысле), который посредством спайдеров, как поисковики, собирает данные о контенте серверов интернет. По-возможности, не пропуская большинство из них. И этот самый контент сохраняет в хранилище.

Оставив пока в покое вопрос, зачем и кому потребовалась и может быть удобна такая машинка, задумайтесь вот о чем. Если ваши данные пролежали в интернете достаточно долго, они с высокой вероятностью есть в этой самой Wayback Machine. Откуда их можно сравнительно легко достать.

Конечно, там есть не все домены и сайты. Но мало-мальски крупные ресурсы находятся без какого-бы то ни было труда. Пример - пожалуйста. А вот гораздо более интересный пример. И еще один интересный пример. И еще пример. Хотите форумы? Пожалуйста.

Что мы увидели? Что данные социальных сетей в архиве есть точно. И, если вы надумали их удалить, то уже, пожалуй, поздновато.

Не надо было выкладывать данные в публичный доступ.

Впрочем, с персональными данными ситуация напоминает джинна, выпущенного из бутылки. Неудержимая тяга к общению привела нас к тому, что инет переполнен персональными данными различной степени незащищенности.

Впрочем, как показывает практика, государства, кроме издания беспомощных законов об охране персональных данных тоже не способно обеспечить охрану этих самых данных. Вопиющая некомпетентность советников и агентств по информатизации привела к тому, что номенклатура, во-первых, физически не понимает сути вопроса, а во-вторых, органические пороки и бреши в системе безопасности баз физических лиц не переминет использовать совсем не во благо этих самых физических лиц. И с этим, к сожалению, тоже уже ничего поделать нельзя.

Давайте попытаемся сохранить хотя бы остатки прайвиси, которая у нас пока есть. И вернемся к нашему эпиграфу. Давайте беречь свои и чужие персональные данные. А не бросаться идиотской фразой "Мне нечего скрывать, я человек честный!"

Персональные данные можно использовать в любых целях. По меньшей мере половина из которых - совсем не безобидна. Начиная от милых рассылок нежелательной рекламы и участия в маркетинговых акциях - и заканчивая прямым причинением ущерба любого масштаба. Прайвиси не должна быть пустым звуком.