The Raspberry Pi 3 is the fastest Raspberry Pi, yet. It also adds onboard wifi and bluetooth. Here are some Pro's and Con's when using your Pi 3 as a ZoneMinder Server.
Alternatively, you can install Fedora 25 using these instructions from the Fedora team. The steps below will be the same.
With Fedberry installed and your Pi booted, you should see the SSD appear as /dev/sda. Let's put this aside for now.
Edit /boot/config.txt and set the parameter gpu_mem=16
We want to use ntpdate instead of ntp since ntpdate does not reside in memory:
Issue sudo crontab -e and create the following crontab entry if it does not already exist:
PROS: | CONS: |
|
|
|
|
|
|
List of Materials
What follows is the list of materials I used to put together this project.- Raspberry Pi 3 (duh)
- Raspberry Pi Power Supply- just pick one
- Micro SD Card. Samsung EVO cards have worked well for me.
- Ableconn USB to mSATA Converter
- 512GB Samsung mSATA SSD
- Stackable Acrylic Case - Cheaper to buy two singles rather than one double
- Short Micro USB cable
- Assorted nylon standoffs (alternatively you can use the metal standoffs included with the acrylic case)
Install Fedora
I started this project before Fedora 25 was released. Consequently, the steps that follow were all performed on a Raspberry Pi 3 running Fedberry, a Fedora 24 spin. If you would like to follow along, simply go to that site and follow the instructions to download and write the Fedberry image file to your sd card. Just make sure and use the minimal image, which does not have a gui.Alternatively, you can install Fedora 25 using these instructions from the Fedora team. The steps below will be the same.
Initial Prep
Assemble the hardware. It should be pretty straightforward. Note that I chose to partition and format the SSD as follows:- 15GB ext4 partition for the Mariadb database files
- 454GB ext4 partition for the ZoneMinder events
- 512MB swap partition
- 512 MB empty space at end of drive
With Fedberry installed and your Pi booted, you should see the SSD appear as /dev/sda. Let's put this aside for now.
Edit /boot/config.txt and set the parameter gpu_mem=16
vi /boot/config.txtWe now want to modify /etc/fstab. Fedberry uses a swap file, rather than a swap partition. We will change this. In addition, we will increase the size of the ramdisk, /dev/shm. Increasing the size of /dev/shm is a balancing act. You don't want to increase it too much. Otherwise you eat into the memory needed by the os, which can cause other problems. For now, use the value shown below. You can always change it again later once you get your cameras online:
We want to use ntpdate instead of ntp since ntpdate does not reside in memory:
sudo dnf remove ntp
sudo dnf install ntpdate
Issue sudo crontab -e and create the following crontab entry if it does not already exist:
0 0 * * * /usr/libexec/ntpdate-wrapper
Install the ZoneMinder RPM
In order to conserver memory, I put together an rpm which depends on nginx, rather than Apache. All you have to do is install it. The rpm will configure nginx for you.
To get it, hop on over to zmrepo.zoneminder.com and follow the installation instructions shown on the site. However, after zmrepo has been installed, instead of issuing yum install zoneminder do the following:
Stop mariadb and move the sql files onto the ssd:
Enable and start the mount unit
Enable and start the mount unit
- Edit the file /etc/yum.repos.d/zmrepo-fedora-testing.repo and set the enabled flag under the [zmrepo-testing] block to 1.
- Now enter sudo dnf install zoneminder-nginx from the command line
- Finish up by following the steps in the README
Followup Configuration
1 2 3 4 | # Uncomment these on machines with little memory pm = ondemand pm.max_children = 10 pm.process_idle_timeout = 10s |
Stop mariadb and move the sql files onto the ssd:
sudo suNow create the file /etc/systemd/system/var-lib-mysql.mount and add the following to it:
systemctl stop mariadb
cd /mnt
mkdir sda1
mount /dev/sda1 /mnt/sda1
chown mysql:mysql /mnt/sda1
mv /var/lib/mysql/* /mnt/sda1/
umount /mnt/sda1
exit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # systemd mount unit for mysql storage [Unit] Description=systemd mount unit for mysql storage Before=mariadb [Mount] What=/dev/disk/by-uuid/put_the_uuid_of_sda1_here Where=/var/lib/mysql Type=ext4 Options=defaults,noatime,commit=120,data=writeback [Install] WantedBy=multi-user.target |
Enable and start the mount unit
sudo systemctl enable var-lib-mysql.mountIf successful, start mariadb back up:
sudo systemctl start var-lib-mysql.mount
sudo systemctl start mariadbLet's do the same thing now for the ZoneMinder events folder
sudo suCreate the file /etc/systemd/system/var-lib-zoneminder-events.mount and add the following to it:
systemctl stop zoneminder
cd /mnt
mkdir sda2
mount /dev/sda2 /mnt/sda2
chown nginx:nginx /mnt/sda2
mv /var/lib/zoneminder/events/* /mnt/sda1/
umount /mnt/sda2
exit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # systemd mount unit for ZoneMinder event storage [Unit] Description=systemd mount unit for ZoneMinder event storage Before=zoneminder [Mount] What=/dev/disk/by-uuid/put_the_uuid_of_sda2_here Where=/var/lib/zoneminder/events Type=ext4 Options=defaults,noatime,commit=120,data=writeback [Install] WantedBy=multi-user.target |
Enable and start the mount unit
sudo systemctl enable var-lib-zoneminder-events.mountAs a final step, we want to limit the amount of memory mariadb uses. There are several sample config files found in /usr/share/mysql which can help us do that. I chose the file my-medium.cnf:
sudo systemctl start var-lib-zoneminder-events.mount
sudo cp /usr/share/mysql/my-medium.cnf /etc/my.cnf.d/Now edit my-medium.cnf and make the following changes:
- Un-comment skip-networking
- Un-comment all of the innodb_ parameters
sudo systemctl restart mariadbYou can now start zoneminder. You did remember to follow the steps in the README, right? If you didn't, this is the point where things will start to go wrong for you.
sudo systemctl start zoneminderAt this point, you should be able to navigate to the ZoneMinder web console and start adding cameras. When adding a new monitor, decrease the image buffer for each new monitor from 50 to 35. This will save quite a bit of memory.
Performance
Here is a summary using sysbench:- cpu - 363.6433s
- event storage drive - 18.307Mb/sec
- database - 406.27 transactions per sec
Cameras
As you add cameras, ZoneMinder will consume space in your ramdisk, /dev/shm. You need to keep a close eye on this at all times. To make this easier, future versions of ZoneMinder will display the percent full in the top right of the web console. You should ensure there is at least ~200MB free of /dev/shm space. Other processes running on your system use the ramdisk. If you are just a little shy of the the target free space, consider increasing the size of /dev/shm a little bit further as described earlier.You also need to keep an eye on your system load. A good not-to-exceed value for the raspberry pi is ~2.5 and ~3 while streaming a live view. Generally, you want to leave a free cpu core to perform non-ZoneMinder related tasks.
Not leaving enough "wiggle room" with cpu and ram resources is a leading cause of why ZoneMinder stops or crashses on its own over time.
I put the following table together to give you a rough estimate of how many resources are consumed as camera resolution is increased:
camera | format | resolution | fps | ring buffer (frames) | mmap (MB) | Max swap buffer (MB) | Zma (%) | Zmc (%) | Zms (%) |
Airlink777W | mjpeg | VGA | 5 | 35 | 42 | 24 | 10 | 5 | 10 |
raspicam | h264 | 720p | 5 | 35 | 124 | 74 | 30 | 20 | 30 |
USGLBH245S400 | h264 | 1080P | 5 | 35 | 277 | 176 | 95 | 50 | 55 |
As you can see, cpu and memory resources go up considerably as the resolution is increased. The cpu values are average over time. These values will spike when movement occurs within the field of view.
Note this data is only valid at 5 fps. CPU resources are expected go up linearly with an increase in frame rate e.g. double the frame, double the processing required.
From the table, you could theoretically attach ten VGA resolution cameras without any problem. Disk i/o might become the bottleneck in that case with so many cameras. However, jump up to 720p and a reasonable number is just three before you run out of space in your ramdisk.
Notice how the zms process for just a single 1080p camera consumed an entire cpu core! This is actually too much. Over a period of days, this camera would fall offline and reconnect, over and over, due to the excessive load. This is what drove me to look for a faster single board computer. Perhaps you will get better results, but at this time I would not recommend using a 1080p camera with a Raspberry Pi 3, unless you are willing to drop the frame rate even lower than 5.